文档介绍:-
. z.
校验原理
1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
2、生成CRC码的基本原理:任意一个由二进/ CRC  初值
  ptr = crcbuff;              //  指向第一个 Byte 数据
  crc = crc
-
. z.
16l(ptr,8);           
  while(1);
}
 
uint crc16l(uchar *ptr,uchar len)        // ptr 为数据指针,len 为数据长度
{
  uchar i;
  while(len--)
  {
      for(i=0*80; i!=0; i>>=1)
    {
        if((crc&0*8000)!=0) {crc<<=1; crc^=0*1021;}        1-1  
          else crc<<=1;                     1-2
      if((*ptr&i)!=0) crc^=0*1021;                       1-3  
    }
    ptr++;
  }
  return(crc);
}
 
执行结果 crc = 0*dbc0;
程序 1-1,1-2,1-3 可以理解成移位前 crc  的 Bit15 与数据对应的 Bit(*ptr&i)做 *OR运算,根据此结果来决定是否执行 crc^=0*1021。只要明白两次异或运算与原值相同,就不难理解这个程序。
 
很多资料上都写了查表法来计算,当时是怎么也没想通。其实蛮简单的。假设通过移位处理了 8 个 bit 的数据,相当于把之前的 CRC 码的高字节(8bit)全部移出,与一个 byte 的数据做*OR 运算,根据运算结果来选择一个值(称为余式),与原来的 CRC 码再做一次 *OR 运算,就可以得到新的 CRC 码。
 
不难看出,余式有 256 种可能的值,实际上就是 0~255 以 *16+*12+*5+1 为权得到的 CRC码,可以通过函数 crc
-
. z.
16l来计算。以1 为例。
 
code test[]={0*01};
crc = 0;
ptr = test;
crc = crc16l(ptr,1);
 
执行结果 crc = 1021,这就是1 对应的余式。
 
进一步修改函数,我这里就懒得写了,可得到 *16+*12+*5+1 的余式表。
 
code uint crc_ta[256]={                // *16+*12+*5+1  余式表
    0*0000, 0*1021,  0*2042, 0*3063, 0*4084, 0*50a5, 0*60c6, 0*70e7,
  0*8108, 0*9129, 0*a14a, 0*b16b, 0*c18c, 0*d1ad, 0*e1ce, 0*f1ef,
    0*1231, 0*0210, 0*3273, 0*2252, 0*52b5, 0*4294, 0*72f7, 0*62d6,
    0*9339, 0*8318, 0*b37b, 0*a35a, 0*d3bd, 0*c39c, 0*f3ff, 0*e3de,
    0*2462, 0*3443, 0*0420, 0*1401, 0*64e6, 0*74c7, 0*44a4, 0*5485,
    0*a56a, 0*b54b, 0*8528, 0*9509, 0*e5ee, 0*f5cf, 0*c5ac, 0*d58d,
    0*3653, 0*2672, 0*1611, 0*0630, 0*76d7, 0*66f6, 0*5695, 0*46b4,
    0*b75b, 0*a77a, 0*9719, 0*8738, 0*f7df, 0*e7fe, 0*d79d, 0*c7bc,
    0*48c4, 0*58e5, 0*6886, 0*78a7, 0*0840, 0*1861, 0*2802, 0*3823,
    0*c9cc, 0*d9ed, 0*e98e, 0*f9af, 0*8948, 0*9969, 0*a90a, 0*b92b,
    0*5