免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3253 | 回复: 3
打印 上一主题 下一主题

CRC程序求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-08 11:12 |只看该作者 |倒序浏览

  1. typedef unsigned char uchar;
  2. typedef unsigned short int int16;
  3. uchar crcbuff [] = { 0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3};
  4. uchar crcbuff2 [] = { 0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3,0x0,0x0};  // 末尾补16个0
  5. int16 crc16_1(uchar *ptr,uchar len);
  6. int16 crc16_2(uchar *ptr,uchar len);
  7. int main(void)
  8. {
  9.     int16 crc;  // CRC 初值
  10.     crc = crc16_1(crcbuff,8);
  11.     printf("%x \n",crc);
  12.     crc = crc16_2(crcbuff2,10);
  13.     printf("%x \n",crc);
  14.     return 0;
  15. }
  16. int16 crc16_1(uchar *ptr,uchar len) // ptr 为数据指针,len 为数据长度
  17. {
  18.     uchar i;
  19.     int16 crc =0;
  20.     while(len--)
  21.     {
  22.         for(i=0x80; i!=0; i>>=1)
  23.         {
  24.             if((crc&0x8000)!=0){
  25.                 crc<<=1;
  26.                 crc^=0x1021;
  27.             }
  28.             else crc<<=1;
  29.                 if((*ptr&i)!=0)        //   ???
  30.                     crc^=0x1021;   // 再加上本位的CRC (看不懂)
  31.         }
  32.         ptr++;
  33.     }
  34.     return(crc);
  35. }

  36. int16 crc16_2(uchar *ptr,uchar len)
  37. {
  38.     int i;
  39.     int16 crc = 0;
  40.     while(len--)
  41.     {
  42.         for(i=7; i>=0; i--)
  43.         {
  44.             crc<<=1;                              // 将CRC寄存器左移一位
  45.             crc |= ((*ptr >> i) & 0x1);     // 将数据的下一位放进CRC寄存器的最低位
  46.             if((crc&0x8000)!=0){
  47.                 crc ^= 0x1021;                // 最高位不为0与0x1021异或
  48.             }
  49.         }
  50.         ptr++;
  51.     }
  52.     return crc;
  53. }
复制代码

上面是代码,crc16_1()是从网上找的,crc16_2()是自己写的,???处不明白是什么意思,
两个函数算出来的结果不一样,至少有一个错了,呵呵
请各位指点,看了许多资料都是抄来抄去

附件是 CRC 算法原理及C 语言实现

[ 本帖最后由 zllfdd 于 2007-5-8 11:14 编辑 ]

200647175616543.pdf

35.26 KB, 下载次数: 200

论坛徽章:
0
2 [报告]
发表于 2007-05-08 17:30 |只看该作者
在8次循环中,i分别等于0x80,0x40,x20,0x10, 0x08, 0x04, 0x02, 0x01

(*ptr & i) != 0

判断 *ptr 第n位是否为1 (n=7...0)

论坛徽章:
0
3 [报告]
发表于 2007-05-09 08:34 |只看该作者
上面的crc16_2()有错,正确的如下:
现在三个计算出的结果相同,只是不太明白为什么crc16_1()和crc16_3()也能计算出正确结果,
我再想想。


  1. typedef unsigned char uchar;
  2. typedef unsigned short int int16;

  3. uchar crcbuff [] = { 0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3};
  4. uchar crcbuff2 [] = { 0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3,0x0,0x0};

  5. int16 crc16_1(uchar *ptr,uchar len);
  6. int16 crc16_2(uchar *ptr,uchar len);
  7. int16 crc16_3(uchar *buf,int   len);

  8. int main(void)
  9. {
  10.     int16 crc;
  11.     crc = crc16_1(crcbuff,8);
  12.     printf("%x \n",crc);
  13.     crc = crc16_2(crcbuff2,10);
  14.     printf("%x \n",crc);
  15.     crc = crc16_3(crcbuff,8);
  16.     printf("%x \n",crc);
  17.     return 0;
  18. }
  19. int16 crc16_1(uchar *ptr,uchar len) // ptr 为数据指针,len 为数据长度
  20. {
  21.     uchar i;
  22.     int16 crc =0;
  23.     while(len--)
  24.     {
  25.         for(i=0x80; i!=0; i>>=1)
  26.         {
  27.             if((crc&0x8000)!=0){
  28.                 crc<<=1;
  29.                 crc^=0x1021;
  30.             }
  31.             else crc<<=1;
  32.                 if((*ptr&i)!=0)
  33.                     crc^=0x1021;   // 再加上本位的CRC
  34.         }
  35.         ptr++;
  36.     }
  37.     return(crc);
  38. }

  39. int16 crc16_2(uchar *ptr,uchar len)
  40. {
  41.     int i;
  42.     int16 crc = 0;
  43.     while(len--)
  44.     {
  45.         for(i=7; i>=0; i--)
  46.         {
  47.             if((crc&0x8000)!=0){
  48.                 crc<<=1;
  49.                 crc |= ((*ptr >> i) & 0x1);
  50.                 crc ^= 0x1021;
  51.             }
  52.             else{
  53.                 crc<<=1;
  54.                 crc |= ((*ptr >> i) & 0x1);
  55.             }
  56.         }
  57.         ptr++;
  58.     }
  59.     return crc;
  60. }

  61. int16 crc16_3(uchar *buf, int len)
  62. {
  63.     unsigned short crc = 0;
  64.     while (--len >= 0) {
  65.         int i;
  66.         crc ^= (unsigned short) *buf++ << 8;
  67.         for (i = 0; i < 8; i++)
  68.             if (crc & 0x8000)
  69.                 crc = crc << 1 ^ 0x1021;
  70.             else
  71.                 crc <<= 1;
  72.     }
  73.     return crc;
  74. }

复制代码

[ 本帖最后由 zllfdd 于 2007-5-9 08:36 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-05-09 13:59 |只看该作者
支持一下,贴一个我的crc交验供参考 :)

  1. static unsigned char CRC_table_h[] =
  2. {
  3.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  4.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  5.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  6.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  7.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  8.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  9.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  10.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  11.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  12.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  13.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  14.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  15.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  16.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  17.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  18.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  19.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  20.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  21.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  22.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  23.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  24.     0x00, 0xC1, 0x81, 0x40
  25. };

  26. static unsigned char CRC_talbe_l[] =
  27. {
  28.     0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
  29.     0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
  30.     0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
  31.     0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
  32.     0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  33.     0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
  34.     0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
  35.     0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
  36.     0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
  37.     0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  38.     0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
  39.     0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
  40.     0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
  41.     0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
  42.     0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  43.     0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
  44.     0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
  45.     0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
  46.     0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
  47.     0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  48.     0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
  49.     0x41, 0x81, 0x80, 0x40
  50. };

  51. int calcCRC16( unsigned char* buf, int len )
  52. {
  53.     unsigned char high = 0;
  54.     unsigned char low = 0;
  55.     int index = 0;
  56.     for( int i = 0; i < len; i++ )
  57.     {
  58.         index = low ^ buf[i];
  59.         low = high ^ CRC_table_h[index];
  60.         high = CRC_talbe_l[index];
  61.     }
  62.    
  63.     index = high;
  64.     index = index << 8;
  65.     index |= low;
  66.     return index;
  67. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP