当前位置:文档之家› CRC16、CRC32校验简单分析

CRC16、CRC32校验简单分析

CRC16校验分析
工业通讯中传输的数据一般是先传数据字节的低位,如:实际DATA 0x38 (0011 1000) 接收端收到为0001 1100 (0x1C),所以大部分CRC校验是处理颠倒的字节数据。

有的多项式简式为0x1021(本文以0x8005为主),目前主要的CRC算法有查表法和直接计算:
1.直接计算
由于数据是颠倒的所以生成项亦要倒置:0xa001(原生成多项式CRC码为0x18005,最高位始终为1故简写为0x8005,反置得到0xa001。

计算CRC时也要从其低位开始运算,且计算中数据右移(移出高位)。

异或运算满足交换律:(A^B)^C=A^(B^C),下面分析其中一种简单算法:
C语言计算:
计算时一次计算8bits,数据与CRC生成多项式(简式)相除,除不尽的余数与下8bits数据再异或(相减),接着进入下一8bits计算。

直到len长的数据全部计算完。

2.查表法:
通过分别计算8bits(查表得到其余式)来实现逐个字节数据的
CRC
计算,直到全部字节数据计算完最后的余式就是CRC。

下面全是8bits查询表(256个余式的表)
,不过也可以4bits查询一次的计算(这样表里只需16个余式).先看程序的算法:
r=0; //r是寄存器,先初始化为0
//p0),t是查询表
字节数据
查询r高8位对应的余式,再
与新得到的式子异或
数据计算示意图:

之后再重复上面的步骤
……若待测数据未扩展0,则此时还要计算4字节扩展0的CRC:
构造CRC32查询表:
一般来说,计算CRC是用“直驱表法”算法计算的,它与上面的算法非常相似,下面分析它的计算:计算步骤为(摘自文献):
1. Shift the register left by one byte
2. XOR the top byte just rotated out of the register with the next message byte
to yield an index into the table ([0,255]).
3. XOR the table value into the register.
4. Goto 1 iff more augmented message bytes.
C语言算法为:
r=0; //r是寄存器,先初始化为0
while (len--) //len是待测数据(不用扩展0)的字节长度
r = (r<<8) ^ t[(r >> 24) ^ *p++]; //p是指向待测数据的指针,t是查询表
相当于通过移位处理了8 个bit 的数据,相当于把之前的CRC 码的高字节(8bit)全部移出,与一个byte 的数据做XOR 运算,根据运算结果来选择一个值(称为余式),与原来的CRC 码再做一次XOR 运算,就可以得到新的CRC 码。

p指向Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ、Ⅵ……字节数据,r为CRC32余式值,t为查询表。

实际上收到的数据一般是先收数据的低位,最后收到字节数据的高位,这样将数据反置了,于是算法只需稍作更改也可算出:
1. 将寄存器向右移动一个字节。

2. 将刚移出的那个字节与待测数据中的新字节做XOR运算,得到一个指向查询表的索引值。

3. 将索引所指的表值与寄存器做XOR运算。

4. 如数据没有全部处理完,则跳到步骤1。

算法为:
r=0; //r是寄存器,先初始化为0
for(i=0; i <len; i++) //len是待测数据(不用扩展0)的字节长度
{
r = t[( r^(*(p+i)) ) & 0xff] ^ (r >> 8); //p是指向待测数据的指针,t是查询表
}
注意此时的查询表不再是前文那个查询表了,它也是一个颠倒的查询表:。

相关主题