126 lines
4.0 KiB
C++
126 lines
4.0 KiB
C++
/*
|
||
* CCRC.h
|
||
*
|
||
* Created on: 25 дек. 2014 г.
|
||
* Author: Gorbunov_DV
|
||
*/
|
||
|
||
#ifndef CCRC_H_
|
||
#define CCRC_H_
|
||
|
||
//! \brief Модуль расчета контрольной суммы по табличному алгоритму CRC
|
||
/*! \details Модуль реализует параметрируемый алгоритм расчета контрольной суммы.
|
||
* В качестве параметров выступают:
|
||
* *Степень алгоритма
|
||
* *Полином
|
||
* *Начальное значение контрольной суммы
|
||
* *Указание, обращать ли входные байты
|
||
* *Указание, обращать ли результат перед выдачей
|
||
* *Значение, которое комбинируется с результатом расчета контрольной суммы перед выдачей
|
||
*
|
||
* \author Gorbunov_DV
|
||
*/
|
||
|
||
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
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 <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
Crc<width, poly, init, refin, refout, xorout>::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 <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
unsigned long Crc<width, poly, init, refin, refout, xorout>::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 <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
unsigned long Crc<width, poly, init, refin, refout, xorout>::calc( char *data, short size )
|
||
{
|
||
crc = init;
|
||
|
||
while( size-- )
|
||
crc = CRCTable[(( crc >> (width - 8) ) ^ *data++ ) & 0xFF] ^ ( crc << 8 );
|
||
|
||
return widmask() & ( crc ^ xorout );
|
||
}
|
||
|
||
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
unsigned long Crc<width, poly, init, refin, refout, xorout>::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 <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
|
||
unsigned long Crc<width, poly, init, refin, refout, xorout>::CRCTable[256];
|
||
|
||
#endif /* CCRC_H_ */
|