CRC-CCITT 算法问题
有一块 通信上要用到 CRC-CCITT算法, 我在网上找了n个算法算出的结果有好几种,请大伙帮忙看看, 哪个是对的 那个是错的。
还有我的校验跟对方的算法算出来总是不一样, 我只知道他们的一组数据算出来的结果:
数据: 0x47,0x01,0x11,0x05,0x01,0x23,0x45,
0x67,0x01,0x23,0x45,0x67,0x11,0x22,
0x33,0x44,0x00,0x02,0x40,0x09
算出来的校验值是: 0x1659
不知道他们是怎么算的,跟网上找的都不一样, 那位大哥手里有算法算出来是这个结果啊!
[解决办法]
同样是CRC初值,多项式,进位顺序等参数不同,结果就不一样...
typedef crc_helper< unsigned short, 0x8005, 0, 0, true >crc16;
typedef crc_helper< unsigned short, 0x3D65, 0, 0 >crcdnp;
typedef crc_helper< unsigned short, 0x8408, 0, 0, true >crc_xmodem;
typedef crc_helper< unsigned short, 0x1021 >crc_itu;
typedef crc_helper< unsigned short, 0x1021, 0xFFFF >crc_itu_ffff;
typedef crc_helper< unsigned short, 0x1021, 0x1D0F >crc_itu_1d0f;
typedef crc_helper< unsigned int, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true >crc32;
typedef crc_helper< unsigned int, 0x1EDC6F41, 0, 0, true >crc32c;
这是我以前写的CRC用到的参数,你可以参考一下.实在不行,可以试下BOOST,看有没有能对得上的算法.
[解决办法]
用以下程序搜索,当CRC的初值取0X164F,可算出0X1659.
#include <stdio.h>unsigned short init_value;unsigned short crc16(unsigned char d[], int len){ unsigned char b = 0; unsigned short crc = init_value; //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; } } return crc;}int main (){ unsigned char d[] = { 0x47,0x01,0x11,0x05,0x01,0x23,0x45, 0x67,0x01,0x23,0x45,0x67,0x11,0x22, 0x33,0x44,0x00,0x02,0x40,0x09 }; unsigned short crc; for (init_value = 1; init_value < 0xffff; init_value++) { crc = crc16(d, sizeof(d)); if (crc == 0x1659) { printf("init_value=%x crc=%x\n", init_value, crc); } } return 0;}
[解决办法]
CRC-CCITT的多项式是1021,但计算时初值不同,最终结果也不同。对于LZ给出的一组数据,要使最终结果为0x1659,那么初值应是0X164F。14楼中的函数crc16就是CRC-CCITT的一种实现,但这里是为了搜索初值,所以把初值定义为一个变量init_value。在作为CRC-CCITT的计算函数时,可写为:
unsigned short crc16(unsigned char d[], int len){ unsigned char b = 0; unsigned short crc = 0x164F; 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; } } return crc;}