查表法和计算法算出来的CRC结果高低位相反,为什么?(附:源程序) 点击:3285 | 回复:3



戴陈海

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:18帖 | 75回
  • 年度积分:0
  • 历史总积分:263
  • 注册:2003年2月19日
发表于:2004-11-24 09:38:00
楼主
一、查表法: // 计算CRC,并返回CRC结果 unsigned int fcs_calc(const unsigned int *crctab, unsigned char *buff, unsigned int len) { unsigned int fcs; unsigned int q; // 临时寄存器 fcs = 0xFFFF; // 初始化CRC寄存器FCS while(len--) { q = *(crctab+(*buff++^(fcs>>8))); fcs = ((q&0xFF00)^(fcs<<8))|(q&0x00FF); } return(fcs);//^0xFFFF);// 将FCS(与0xFFFF异或值)作为CRC计算结果返回 } // 16位CRC计算常数表 const unsigned int crctab[256]= { 0x0000, 0xC1C0, 0x81C1, 0x4001, 0x01C3, 0xC003, 0x8002, 0x41C2, 0x01C6, 0xC006, 0x8007, 0x41C7, 0x0005, 0xC1C5, 0x81C4, 0x4004, 0x01CC, 0xC00C, 0x800D, 0x41CD, 0x000F, 0xC1CF, 0x81CE, 0x400E, 0x000A, 0xC1CA, 0x81CB, 0x400B, 0x01C9, 0xC009, 0x8008, 0x41C8, 0x01D8, 0xC018, 0x8019, 0x41D9, 0x001B, 0xC1DB, 0x81DA, 0x401A, 0x001E, 0xC1DE, 0x81DF, 0x401F, 0x01DD, 0xC01D, 0x801C, 0x41DC, 0x0014, 0xC1D4, 0x81D5, 0x4015, 0x01D7, 0xC017, 0x8016, 0x41D6, 0x01D2, 0xC012, 0x8013, 0x41D3, 0x0011, 0xC1D1, 0x81D0, 0x4010, 0x01F0, 0xC030, 0x8031, 0x41F1, 0x0033, 0xC1F3, 0x81F2, 0x4032, 0x0036, 0xC1F6, 0x81F7, 0x4037, 0x01F5, 0xC035, 0x8034, 0x41F4, 0x003C, 0xC1FC, 0x81FD, 0x403D, 0x01FF, 0xC03F, 0x803E, 0x41FE, 0x01FA, 0xC03A, 0x803B, 0x41FB, 0x0039, 0xC1F9, 0x81F8, 0x4038, 0x0028, 0xC1E8, 0x81E9, 0x4029, 0x01EB, 0xC02B, 0x802A, 0x41EA, 0x01EE, 0xC02E, 0x802F, 0x41EF, 0x002D, 0xC1ED, 0x81EC, 0x402C, 0x01E4, 0xC024, 0x8025, 0x41E5, 0x0027, 0xC1E7, 0x81E6, 0x4026, 0x0022, 0xC1E2, 0x81E3, 0x4023, 0x01E1, 0xC021, 0x8020, 0x41E0, 0x01A0, 0xC060, 0x8061, 0x41A1, 0x0063, 0xC1A3, 0x81A2, 0x4062, 0x0066, 0xC1A6, 0x81A7, 0x4067, 0x01A5, 0xC065, 0x8064, 0x41A4, 0x006C, 0xC1AC, 0x81AD, 0x406D, 0x01AF, 0xC06F, 0x806E, 0x41AE, 0x01AA, 0xC06A, 0x806B, 0x41AB, 0x0069, 0xC1A9, 0x81A8, 0x4068, 0x0078, 0xC1B8, 0x81B9, 0x4079, 0x01BB, 0xC07B, 0x807A, 0x41BA, 0x01BE, 0xC07E, 0x807F, 0x41BF, 0x007D, 0xC1BD, 0x81BC, 0x407C, 0x01B4, 0xC074, 0x8075, 0x41B5, 0x0077, 0xC1B7, 0x81B6, 0x4076, 0x0072, 0xC1B2, 0x81B3, 0x4073, 0x01B1, 0xC071, 0x8070, 0x41B0, 0x0050, 0xC190, 0x8191, 0x4051, 0x0193, 0xC053, 0x8052, 0x4192, 0x0196, 0xC056, 0x8057, 0x4197, 0x0055, 0xC195, 0x8194, 0x4054, 0x019C, 0xC05C, 0x805D, 0x419D, 0x005F, 0xC19F, 0x819E, 0x405E, 0x005A, 0xC19A, 0x819B, 0x405B, 0x0199, 0xC059, 0x8058, 0x4198, 0x0188, 0xC048, 0x8049, 0x4189, 0x004B, 0xC18B, 0x818A, 0x404A, 0x004E, 0xC18E, 0x818F, 0x404F, 0x018D, 0xC04D, 0x804C, 0x418C, 0x0044, 0xC184, 0x8185, 0x4045, 0x0187, 0xC047, 0x8046, 0x4186, 0x0182, 0xC042, 0x8043, 0x4183, 0x0041, 0xC181, 0x8180, 0x4040 }; 二、计算法: // 计算数据数组D[k]的CRC校验结果 unsigned int buff=0; bool blCr=false; unsigned int CrcReg = 0xFFFF; // 校验寄存器 for(unsigned int n=0;n<k;n++) { buff = CrcReg & 0x00FF; buff = buff ^ d[n]; CrcReg = CrcReg & 0xFF00; CrcReg += buff; for(int m=0;m<8;m++) { if(CrcReg & 1) blCr=true; else blCr=false; CrcReg = CrcReg >> 1; if(blCr) CrcReg = CrcReg ^ 0xA001; } } 我用两种算法算出来的结果正好高低位是相反的,看了网络上的CRC算法,有的查表法的常数表跟我的是高低位相反的,也有的是一致的,这使我比较迷茫。 请众家高手不吝指教!


楼主最近还看过



houyx

  • 精华:0帖
  • 求助:0帖
  • 帖子:8帖 | 64回
  • 年度积分:0
  • 历史总积分:122
  • 注册:2003年11月29日
发表于:2005-05-09 08:57:00
1楼
我用的CRC是查表法,好像高低位也出现了一些颠倒

周公

  • 精华:10帖
  • 求助:0帖
  • 帖子:119帖 | 5549回
  • 年度积分:0
  • 历史总积分:6446
  • 注册:2002年11月26日
发表于:2005-05-10 18:51:00
2楼
如果是8051系列单片机,要注意双字节变量存储的位置是高低字节前后相反

戴陈海

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 75回
  • 年度积分:0
  • 历史总积分:272
  • 注册:2003年2月19日
发表于:2007-12-22 14:44:00
3楼
经过我反复验证,的确是存储位置定义差异产生的。编译器不相同,定义也不同。同行们使用的时候一定要算几个值实际验证一下。如果发现颠倒了,就直接换一下高低位就可以了。两种算法都没问题。

热门招聘
相关主题

官方公众号

智造工程师