CRC其实也就那么回事,却在网上被传得神乎其神。单纯从使用角度来说,只需要搞明白模二除法,再理解一些偷懒优化的技巧,就能写出自己的CRC校验程序。
下面的代码完全是模拟手算过程的,效率是最低的,发出来是为了对比后面高效的查表法等。
*CRC校验程序*/ //输入32位 //多项式,省略最高位1 0x4C11DB7 CCITT-32: 0x04C11DB7 = x32 + x26 + x23 + x22 + x16 + x12 + // x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 //数据不反向 结果不反向 //初值0x00000000或0xFFFFFFFF,其实所谓的初值就是原始数据要不要跟0xFFFFFFFF先异或先放到Reg中计算,用0xFFFFFFFF只是为了让别人不 //会一下就看出生成多项式是多少 //结果不异或 //验证网址:http://www.zorc.breitbandkatze.de/crc.html //算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0 u32 CRC_Check_Software(u8 *ucpData,u8 Length) { u32 poly=0x4C11DB7; //生成多项式 u32 Reg=0xFFFFFFFF; u8 i; u8 j=; u8 u32DataLen=((Length/)>)?((Length/)+):(Length/); u32 uipData[]={}; //把byte组合成32位一组的数据放入uipData ;i<Length;i++) { uipData[i/]|=((u32)(*(ucpData+i)))<<(*(j-)); j--; ) { j=; } } ;i<u32DataLen;i++) { Reg=uipData[i]; //Reg^=0xFFFFFFFF;//如果初值为0x00000000就把这行注释掉,否则不要注释 ;j<;j++) { if(Reg&0x80000000) { Reg=Reg<<; //要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成 //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位 Reg^=poly; } else { Reg=Reg<<; } } } return Reg; }
算例:
Initial value 0x00000000
Data sequence "ABCD" Answer:6CCB4718 (hex)
Initial value 0xFFFFFFFF
Data sequence "ABCD" Answer:ABCF9A63 (hex)
好像很多CRC喜欢在最后再把结果与0xffffffff或其他的什么数再异或一把,只要收发端算法一样,爱怎么写怎么写