首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

CRC-CCITT 算法有关问题

2012-05-30 
CRC-CCITT 算法问题有一块 通信上要用到 CRC-CCITT算法, 我在网上找了n个算法算出的结果有好几种,请大伙帮

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.

C/C++ code
#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的计算函数时,可写为:

C/C++ code
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;} 

热点排行