126 lines
4.9 KiB
C++
126 lines
4.9 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_ */
|