CRC-CCITT校验算法有关问题
CRC-CCITT校验算法问题
最近用DMR协议其中用到了CRC-CCITT校验算法,协议中关于其描述如下
Consider the n data bits as the coefficients of a polynomial M(x) of degree n-1, associating the MSB of the zero-th octet
with xn-1 and the LSB of the last octet with x0. Define the generator polynomial, GH(x), and the inversion polynomial,
IH(x).
GH(x) = x16 + x12 + x5 + 1 (B.15)
IH(x) = x15 + x14 + x13 + ... + x2 + x + 1 (B.16)
The CRC polynomial, FH(x), is then computed from the formula:
FH(x) = (x16 M(x) mod GH(x)) + IH(x) (B.17)
modulo 2, i.e. in GF(2).
The coefficients of FH(x) are placed in the CRC field with the MSB of the zero-th octet of the CRC corresponding to
x15 and the LSB of the next octet of the CRC corresponding to x0. For the CRC-CCITT calculation the initial remainder
shall be 000016.
我从网上找了CRC-CCITT的算法程序如下
但是算出了结果不一样,比如一串数据
unsigned char test[10] = {0xb8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 2b};
我自己算出来crc校验位是0x98CB,但是实际答案是0xDC57,谁帮我看看是不是我找的CRC-CCITT算法有问题?
------解决方案--------------------
google crc, 了解一下,每种的多项式不同,多项式常量不同,不是网上找一个就直接可用的,一般protoclo 中有讲
------解决方案--------------------
CRC16的C语言代码:
typedef unsigned short uint16_t;
typedef unsigned char BYTE;
uint16_t crc16_ccitt(BYTE *ucbuf, int iLen)
{
uint16_t crc = 0xFFFF; // initial value
uint16_t polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
for (int j = 0; j < iLen; ++j) {
for (int i = 0; i < 8; i++) {
char bit = ((ucbuf[j] >> (7-i) & 1) == 1);
char c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
return crc;
}
最近用DMR协议其中用到了CRC-CCITT校验算法,协议中关于其描述如下
Consider the n data bits as the coefficients of a polynomial M(x) of degree n-1, associating the MSB of the zero-th octet
with xn-1 and the LSB of the last octet with x0. Define the generator polynomial, GH(x), and the inversion polynomial,
IH(x).
GH(x) = x16 + x12 + x5 + 1 (B.15)
IH(x) = x15 + x14 + x13 + ... + x2 + x + 1 (B.16)
The CRC polynomial, FH(x), is then computed from the formula:
FH(x) = (x16 M(x) mod GH(x)) + IH(x) (B.17)
modulo 2, i.e. in GF(2).
The coefficients of FH(x) are placed in the CRC field with the MSB of the zero-th octet of the CRC corresponding to
x15 and the LSB of the next octet of the CRC corresponding to x0. For the CRC-CCITT calculation the initial remainder
shall be 000016.
我从网上找了CRC-CCITT的算法程序如下
- C/C++ code
void crc16(unsigned char d[], int len) { unsigned char b = 0; unsigned short crc = 0xffff; int i, j; for(i=0; i<len; i++) { for(j=0; j<8; j++) { b = ((d[i]<<j)&0x80) ^ ((crc&0x8000)>>8); crc<<=1; if(b!=0) crc^=0x1021; } } crc = ~crc; printf("crc: 0x%.4X ", crc); }
但是算出了结果不一样,比如一串数据
unsigned char test[10] = {0xb8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 2b};
我自己算出来crc校验位是0x98CB,但是实际答案是0xDC57,谁帮我看看是不是我找的CRC-CCITT算法有问题?
------解决方案--------------------
google crc, 了解一下,每种的多项式不同,多项式常量不同,不是网上找一个就直接可用的,一般protoclo 中有讲
------解决方案--------------------
CRC16的C语言代码:
typedef unsigned short uint16_t;
typedef unsigned char BYTE;
uint16_t crc16_ccitt(BYTE *ucbuf, int iLen)
{
uint16_t crc = 0xFFFF; // initial value
uint16_t polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
for (int j = 0; j < iLen; ++j) {
for (int i = 0; i < 8; i++) {
char bit = ((ucbuf[j] >> (7-i) & 1) == 1);
char c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) crc ^= polynomial;
}
}
crc &= 0xffff;
return crc;
}