140 lines
3.6 KiB
C++
140 lines
3.6 KiB
C++
|
|
//
|
|||
|
|
// Created by titov on 27.11.2021.
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
#include "CrcPolys.hh"
|
|||
|
|
|
|||
|
|
#include <climits>
|
|||
|
|
|
|||
|
|
#ifndef CHAR_BIT
|
|||
|
|
#define CHAR_BIT 8
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
template<typename Param>
|
|||
|
|
uint16_t crc16(const char * data, std::size_t size) {
|
|||
|
|
|
|||
|
|
return common::crc::crcCalc<Param>(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;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BISS CRC6 <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
|
* @param data <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
* @param size <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
* @return @note <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ( <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BISS-C )
|
|||
|
|
*/
|
|||
|
|
uint16_t crcBiSS( const char * data, std::size_t size )
|
|||
|
|
{
|
|||
|
|
//!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> CRC6, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: 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<common::crc::Crc3_GSM>;
|
|||
|
|
crc_instance.bit_size = 3;//common::crc::Crc3_GSM::width_bit;
|
|||
|
|
|
|||
|
|
} break;
|
|||
|
|
case CrcPolynoms::Crc6_BISS: {
|
|||
|
|
|
|||
|
|
common::crc::CrcTable<common::crc::Crc6_BISS>::Instance().inititialize();
|
|||
|
|
|
|||
|
|
crc_instance.poly.crc16 = crcBiSS;
|
|||
|
|
crc_instance.bit_size = 6;
|
|||
|
|
|
|||
|
|
} break;
|
|||
|
|
default: {} break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return crc_instance;
|
|||
|
|
|
|||
|
|
}
|