// // Created by titov on 27.11.2021. // #include "CrcPolys.hh" #include #ifndef CHAR_BIT #define CHAR_BIT 8 #endif template uint16_t crc16(const char * data, std::size_t size) { return common::crc::crcCalc(data, size * CHAR_BIT / 8); } //!width=3 poly=0x3 init=0x0 refin=false refout=false xorout=0x7 check=0x4 residue=0x2 name="CRC-3/GSM" uint16_t crc3GSM( const char * data, std::size_t size ) { uint16_t crc = 0; const unsigned char high_octet_bit = (0x1u << (8 - 1)); for( int n = 0; n < size; ++n ) { unsigned char byte = data[n]; while( byte ) { unsigned char octet = byte & 0xFFu; for( int bit = 0; bit < 8; ++bit ) { bool is_set = (crc & 0x4u) ^ ((octet & high_octet_bit) >> (8 - 3)); octet <<= 1; crc <<= 1; if( is_set ) crc ^= 0x3u; crc &= 0x7u; } byte >>= 8u; } } return crc; } /*! * Функция нахождения контрольной суммы BISS CRC6 при помощи табличного алгоритма. * @param data массив данных, контрольную сумму которых надо расчитать, массив данных необходимо выровнять по младшему биту * @param size количество байт из массива, контрольную сумму которых надо расчитать * @return @note ИНВЕРТИРОВАННАЯ контрольная сумма ( в соответствии с протоколом BISS-C ) */ uint16_t crcBiSS( const char * data, std::size_t size ) { //!Таблица для расчёта чек сумы CRC6, для полинома: P(x) = x6 + x1 + x0 static uint16_t tableCRC6[64] = { 0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21, 0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A, 0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A, 0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02 }; const uint16_t CRC6_BITS = 6; const uint16_t SIX_BITS_MASK = 0x3Fu; uint32_t CHAR_MASK; if( CHAR_BIT == 8 ) { CHAR_MASK = 0xFF; } if( CHAR_BIT == 16) { CHAR_MASK = 0xFFFF; } uint32_t _data = 0; uint16_t crc; uint32_t tmp { 0 }; uint16_t cycle_crc_xor = ( size * CHAR_BIT ) / CRC6_BITS; uint16_t shift = ( size * CHAR_BIT ) - ( size * CHAR_BIT ) % CRC6_BITS; for ( int i = 0; i < size; i++ ) { uint32_t data_tmp = data[ i ]; _data |= ( ( data_tmp ) << ( i * CHAR_BIT ) ) & ( CHAR_MASK << ( i * CHAR_BIT ) ); } uint16_t bits_in_mask = ( 1 << ( CHAR_BIT - ( shift % ( CHAR_BIT ) ) ) ) - 1; tmp = ( _data >> shift ) & bits_in_mask; do { cycle_crc_xor--; crc = ( ( _data >> CRC6_BITS * cycle_crc_xor ) & SIX_BITS_MASK ); tmp = ( ( crc ) ^ tableCRC6[ tmp ] ) & SIX_BITS_MASK ; } while( cycle_crc_xor > 0 ); crc = tableCRC6[tmp]; return ( crc ^ SIX_BITS_MASK ); } common::crc::CrcPolynoms::CrcInstance common::crc::CrcPolynoms::instanse(common::crc::CrcPolynoms::Types type) { CrcInstance crc_instance; switch (type) { case CrcPolynoms::Crc3_GSM: { crc_instance.poly.crc16 = crc3GSM;//&crc16; crc_instance.bit_size = 3;//common::crc::Crc3_GSM::width_bit; } break; case CrcPolynoms::Crc6_BISS: { common::crc::CrcTable::Instance().inititialize(); crc_instance.poly.crc16 = crcBiSS; crc_instance.bit_size = 6; } break; default: {} break; } return crc_instance; }