感受:知其然而知所以然才是学习,模糊的学习最为致命。
crc校验的原理:二进制数的除法与异或(模2)运算
算法实现:
1)概念定义法直接实现:将被除数左移,如果最高位为1,则取异或,为0,则继续左移。直至被除数为0
2)普遍的算法实现:
bit位移(以字节为单位)
查表(以字节为单位)
question:
以字节进行运算的可行性??
论证:http://www.cnblogs.com/esestt/archive/2007/08/09/848856.html
找了两天最好的论证文章,充分论证了正确性(我比较懒,没有罗列计算过程,所以一直存在疑惑,所幸两天后找到了这篇文章)
论证完成后,受启发,写的一段建立表格与计算校验的代码:
#include "stdio.h"
typedef unsigned short uint_16;
uint_16 poly=0x1021;
uint_16 table[0xff+1];
void init_table(){
unsigned char c=0;
int n=0xff,i=0;
while(i<=n){
unsigned short t=c;
t<<=8;
int j;
uint_16 crc=0;
for(j=0;j<8;j++){
if(t&0x8000){
t=(t<<1)^poly;
crc^=(poly<<(7-j));
}else t<<=1;
}
table[i]=crc;
i++;
c++;
}
}
uint_16 crc(unsigned char *s,int size){
int i;
uint_16 crc=0;
for(i=0;i<size;i++){
crc=table[s[i]^(crc>>8)]^(crc<<8);
}
return crc;
}
int main(){
init_table();
char s[]={'a','b','c','d'};
printf("%d\n",crc((unsigned char*)s,4));
return 0;
}
学习知识点:
1.余数种类的有限性与确定性,进而得出表格,进行快速计算。
2.理解余数计算所在的位数对应,有利于理解
crc=table[s[i]^(crc>>8)]^(crc<<8)
这行代码。