CRC16 common standards are used in various specifications, the principle of its algorithm is basically consistent, that is, in the data input and output differences, below the standards of the differences listed, and give the C language algorithm implementation.
Crc16_ccitt: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low in front, high in the post, results and 0x0000 different or
Crc16_ccitt_false: Polynomial x16+x12+x5+1 (0x1021), initial value 0xFFFF, low after, high in front, the result is different from 0x0000 or
Crc16_xmodem: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low after, high in front, result with 0x0000 xor or
crc16_x25: Polynomial x16+x12+x5+1 (0x1021), initial value 0x0000, low in front, high after, the result is different from 0xFFFF or
Crc16_modbus: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low in front, high in the rear, the result is different from 0x0000 or
CRC16_IBM: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low in front, high in the post, results and 0x0000 different or
Crc16_maxim: Polynomial x16+x15+x2+1 (0x8005), initial value 0x0000, low in front, high after, the result is different from 0xFFFF or
Crc16_usb: Polynomial x16+x15+x2+1 (0x8005), initial value 0xFFFF, low in front, high in the rear, the result is different from 0xFFFF or
Mode |
Multi-item |
Initial value |
Data bit Order |
Result processing |
Crc16_ccitt |
X16+x12+x5+1 (0x1021) |
0x0000 |
Low in front, high in the back |
Unlike 0x0000 or |
Crc16_ccitt_false |
X16+x12+x5+1 (0x1021) |
0xFFFF |
Low in the back, high in the front |
Unlike 0x0000 or |
Crc16_xmodem |
X16+x12+x5+1 (0x1021) |
0x0000 |
Low in the back, high in the front |
Unlike 0x0000 or |
crc16_x25 |
X16+x12+x5+1 (0x1021) |
0x0000 |
Low in the back, high in the front |
With 0xFFFF XOR or |
Crc16_ MODBUS |
X16+x15+x2+1 (0x8005) |
0xFFFF |
Low in front, high in the back |
Unlike 0x0000 or |
Crc16_ IBM |
X16+x15+x2+1 (0x8005) |
0x0000 |
Low in front, high in the back |
Unlike 0x0000 or |
Crc16_ MAXIM |
X16+x15+x2+1 (0x8005) |
0x0000 |
Low in front, high in the back |
With 0xFFFF XOR or |
Crc16_ USB |
X16+x15+x2+1 (0x8005) |
0xFFFF |
Low in front, high in the back |
With 0xFFFF XOR or |
Multi-item Generation:
such as X16+x12+x5+1
x16 says the 16th bit is 1,x5 for the 5th digit is 1
(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021
But the CRC16 is only 16 digits low, written in the 16 number is 0x1021
CRC16 principle of the algorithm:
1. Select the value of the initial crcin according to the CRC16 criteria.
2. The first byte of the data is higher than the Crcin 8-bit.
3. Judge the highest bit, if the bit is 0 to move left one, if 1 left one again and polynomial hex code different or.
4. Repeat 3 until 8-digit total shift calculation ends. 5. Repeat all input data operations complete the above steps, the resulting 16 digits is 16-bit CRC check code.
According to the algorithm principle and standard requirements can be simple to write the specific procedures:
unsigned short Crc16_ccitt (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0x0000;
unsigned short wcpoly = 0x1021;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
InvertUint8 (&wchar,&wchar);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (wcrcin);
} unsigned short crc16_ccitt_false (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0xFFFF;
unsigned short wcpoly = 0x1021;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly; Else
Wcrcin = wcrcin << 1;
} return (wcrcin);
} unsigned short crc16_xmodem (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0x0000;
unsigned short wcpoly = 0x1021;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} return (wcrcin);
} unsigned short crc16_x25 (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0xFFFF;
unsigned short wcpoly = 0x1021;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
InvertUint8 (&wchar,&wchar);
Wcrcin ^= (WChar << 8); for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (Wcrcin <&lT
1) ^ Wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (WCRCIN^0XFFFF);
} unsigned short crc16_modbus (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0xFFFF;
unsigned short wcpoly = 0x8005;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
InvertUint8 (&wchar,&wchar);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (wcrcin);
} unsigned short crc16_ibm (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0x0000;
unsigned short wcpoly = 0x8005;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++); InvertUint8 (&wchar,&amP;wchar);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (wcrcin);
} unsigned short crc16_maxim (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0x0000;
unsigned short wcpoly = 0x8005;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
InvertUint8 (&wchar,&wchar);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (WCRCIN^0XFFFF); } unsigned short crc16_usb (unsigned char *puchmsg, unsigned int usdatalen) {unsigned short wcrcin = 0xFFFF;
unsigned short wcpoly = 0x8005;
unsigned char WChar = 0;
while (usdatalen--) {WChar = * (puchmsg++);
InvertUint8 (&wchar,&wchar);
Wcrcin ^= (WChar << 8);
for (int i = 0;i < 8;i++) {if (Wcrcin & 0x8000) wcrcin = (wcrcin << 1) ^ wcpoly;
else Wcrcin = wcrcin << 1;
} InvertUint16 (&wcrcin,&wcrcin);
return (WCRCIN^0XFFFF); }
void InvertUint8 (unsigned char *dbuf,unsigned char *srcbuf) { int i; unsigned char tmp[4]; &nb Sp
Tmp[0] = 0; for (i=0;i< 8;i++) { if (srcbuf[0]& (1 << i)) &N Bsp
tmp[0]|=1<< (7-i);
} dbuf[0] = tmp[0]; } void InvertUint16 (unsigned short *dbuf,unsigned short *srcbuf) { int i;
unsigned short tmp[4];
Tmp[0] = 0; for (i=0;i< 16;i++) { if (srcbuf[0]& (1 << i)) & nbsp
tmp[0]|=1<< (15-i);
} dbuf[0] = tmp[0];
} void InvertUint32 (unsigned int *dbuf,unsigned int *srcbuf) { int i; unsigned int tmp[4];
Tmp[0] = 0; for (i=0;i< 32;i++) { if srcbuf[0]& (1 << i) tmp[0]|=1<< (15-i);
} dbuf[0] = tmp[0];
}
Specific validation please use this tool, which includes the calculation of all CRC algorithms
On this basis, we also add CRC32 verification algorithm.
CRC32 algorithm:
unsigned int CRC32 (unsigned char *puchmsg, unsigned int usdatalen)
{
int i;
unsigned int wcrcin = 0xFFFFFFFF;
unsigned int wcpoly = 0X04C11DB7;
unsigned int wChar = 0;
while (usdatalen--)
{
WChar = * (puchmsg++);
InvertUint8 ((unsigned char *) &wchar, (unsigned char *) &wchar);
Wcrcin ^= (WChar <<);
for (i = 0;i < 8;i++)
{
if (wcrcin & 0x80000000)
wcrcin = (wcrcin << 1) ^ wcpoly;
else
wcrcin = wcrcin << 1;
}}
InvertUint32 (&wcrcin,&wcrcin);
Return (wcrcin ^ 0xFFFFFFFF);
}
For CRC32, there may be other polynomials and initial and result values that need to be different, or if the input data requires a bit-order reversal, etc., in the source code changes