再探CRC
之前写了CRC16的程序,虽然能用,却不知其所心然,现在要用CRC32,重温一遍,一下就通了。笔记如下
CRC我没记错的话是Cyclic Redundancy Code,Cyclic和Redundancy十分逼真,所谓冗余便是附加的信息,这便是核算下面的原始数据时为什么原始数据要左移四位的原因,
///
/// The simplest CRC implement algorithm.
///
/*
Load the register with zero bits.
Augment the message by appending Wzerobits to the end of it.
While (more message bits)
Begin
Shift the register left by one bit, reading thenextbit of the augmented message into register bit position 0.
If (a 1 bit popped out of the register during step 3)
Register = Register XOR Poly.
End
The register now contains the remainder.
*/
#include
#define POLY 0x13
int main()
{
/// the data
unsigned short data = 0x035b;
/// load the register with zero bits
unsigned short regi = 0x0000;
/// augment thedataby appending W(4)zerobits to the end of it.
data <<= 4;
/// we do it bit after bit
for( int cur_bit = 15; cur_bit >= 0; — cur_bit )
{
/// test the highest bit which will be poped later.
/// in fact, the 5th bit from right is the hightest bit here
if( ( ( regi >> 4 ) & 0x0001 ) == 0x1 )//凑够5位数(与被除数即生成多项式的位数相同),模2除
{
regi = regi ^ POLY;
}
/// shift the register regi <<= 1;
/// reading thenextbit of the augmented data
unsigned short tmp = (data>> cur_bit ) & 0x0001;
regi |= tmp;
}
/// and now, register contains the remainder which is also called CRC value.
return 0;
}
以上程序便是上面相片里算法的模仿完成,过程完全一致。
Some popular polys are:
16 bits: (16,12,5,0) [X25standard]
(16,15,2,0) [“CRC-16”]
32 bits: (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0) [Ethernet]
咱们常用的CRC生成多项式如上,假如CRC32校验也要按BIT来核算的话,将是一个多么大的工程。所以一般会以BYTE为单位进行核算,由于核算机的寄存器位数都是8的位数。
咱们先来看异或的一个特性,这是咱们打开下面描绘的根底:
仍是相片里的核算比如,这儿把首位为0
Original message : 1101011011
Poly : 10011
Message after appending Wzeros : 11010110110000
Now we simply divide the augmented message by thepolyusing CRC
arithmetic. This is the same division as before:
1100001010 = Quotient (nobody cares about the quotient)
_______________
10011 ) 11010110110000 = Augmented message (1101011011 + 0000)
=Poly 10011,,.,,….
—–,,.,,….
10011,.,,…. //每一次的余数便是寄存器里的当时值,这儿寄存器现已左移了一位,//读入一位新数据
10011,.,,….
—–,.,,….
00001.,,….//首位为0,寄存器内值比除数小,则持续读入下一位
00000.,,….
—–.,,….
00010,,….
00000,,….
—–,,….
00101,….
00000,….
—–,….
01011….
00000….
—–….
10110…
10011…
—–…
01010..
00000..
—–..
10100.
10011.
—–.
01110
00000
—–
1110 = Remainder = THE CHECKSUM!!!!
咱们试另一种算法,把数据1101011011以5位一段分隔:11010,11011
先对11010做对poly的CRC校验,即110100000模2除poly成果是1000,把1000 0000与110110000异或,得到10110000再模2除poly,成果仍是1110与之前的核算成果相同。
看到这儿,你或许想到了,把数据按8位一段区分,先对最高位的byte进行CRC校验,校验值与下一byte异或进行校验。。。。。。。,最终咱们也得到了CRC校验值。