/* * CCRC.h * * Created on: 25 дек. 2014 г. * Author: Gorbunov_DV */ #ifndef CCRC_H_ #define CCRC_H_ //! \brief Модуль расчета контрольной суммы по табличному алгоритму CRC /*! \details Модуль реализует параметрируемый алгоритм расчета контрольной суммы. * В качестве параметров выступают: * *Степень алгоритма * *Полином * *Начальное значение контрольной суммы * *Указание, обращать ли входные байты * *Указание, обращать ли результат перед выдачей * *Значение, которое комбинируется с результатом расчета контрольной суммы перед выдачей * * \author Gorbunov_DV */ template class Crc { private: static unsigned long CRCTable[256]; //!< Таблица полиномов unsigned long crc; //!< Результат вычисления контрольной суммы /*!\brief Функция получения маски в соответствии со степенью алгоритма. */ unsigned long widmask() { return ( ( ( 1L << ( width - 1 ) ) - 1L ) << 1 ) | 1L; } /*!\brief Функция обращения заданного количества бит в передаваемом значении. * \return обращенное значение. * \param[in] value значение для обращения * \param[in] numBits количество бит для обращения */ unsigned long reflect( unsigned long value, short numBits ); public: /*!\brief Конструктор по умолчанию */ Crc(); /*!\brief Функция расчета контрольной суммы блока данных * \return рассчитанная контрольная сумма. * \param[in] data указатель на начало блока данных. * \param[in] size размер блока в байтах. */ unsigned long calc( char *data, short size ); /*!\brief Функция расчета контрольной суммы по частям * \return рассчитанная контрольная сумма. * \param[in] data указатель на начало текущей части данных * \param[in] size размер части данных * \param[in] firstPart признак первой части данных */ unsigned long calcPartial( char *data, short size, bool firstPart ); /*!\brief Функция получения рассчитанной контрольной суммы * \return рассчитанная контрольная сумма. */ unsigned long get() { return widmask() & crc; } }; template Crc::Crc() : /*model(),*/ crc(init) { // инициализация таблицы unsigned long topbit = 1L << ( width - 1 ); unsigned long inbyte; for( int i = 0; i < 256; i++ ) { inbyte = refin ? reflect( i, 8 ) : i; inbyte = inbyte << ( width - 8 ); for( int j = 0; j < 8; j++ ) inbyte = ( inbyte & topbit ) != 0 ? ( inbyte << 1 ) ^ poly : inbyte << 1; CRCTable[i] = ( refin ? reflect(inbyte, width) : inbyte ) & widmask(); } } template unsigned long Crc::reflect( unsigned long value, short numBits ) { unsigned long t = value; for( int i = 0; i < numBits; i++ ) { if( t & 1L ) value |= 1L << ( (numBits-1) - i ); else value &= ~( 1L << ( (numBits-1) - i ) ); } return value; } template unsigned long Crc::calc( char *data, short size ) { crc = init; while( size-- ) crc = CRCTable[(( crc >> (width - 8) ) ^ *data++ ) & 0xFF] ^ ( crc << 8 ); return widmask() & ( crc ^ xorout ); } template unsigned long Crc::calcPartial( char *data, short size, bool firstPart ) { if( firstPart ) crc = init; while( size-- ) crc = CRCTable[(( crc >> (width - 8) ) ^ *data++ ) & 0xFF] ^ ( crc << 8 ); return widmask() & ( crc ^ xorout ); } template unsigned long Crc::CRCTable[256]; #endif /* CCRC_H_ */