Linux基础(三)——CRC16算法与程序

循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC。它是利用除法及余数的原理来作错误侦测(Error Detecting)的。实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CRC值不同,则说明数据通讯出现错误。

    CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果 LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。

下面为CRC16的计算过程,其中生成多项式为:X16+X15+X2+1:

1.设置CRC寄存器,并给其赋值FFFF(hex)。

2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。

3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。

4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与生成多项式码相异或。

5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。

6.重复第2至第5步直到所有数据全部处理完成。

7.最终CRC寄存器的内容即为CRC值。

/******************************************************************

CRC16校验和计算icmp_cksum

参数:

	data:数据

	len:数据长度

返回值:

	计算结果,short类型

******************************************************************/

static unsigned short icmp_cksum(unsigned char *data,  int len)

{

    int sum=0;

	int odd = len & 0x01;/*是否为奇数*/



	unsigned short *value = (unsigned short*)data;

	/*将数据按照2字节为单位累加起来*/

       while( len & 0xfffe)  {

              sum += *(unsigned short*)data;

		data += 2;

		len -=2;

       }

	/*判断是否为奇数个数据,若ICMP报头为奇数个字节,会剩下最后一字节。*/

       if( odd) {

		unsigned short tmp = ((*data)<<8)&0xff00;

              sum += tmp;

       }

       sum = (sum >>16) + (sum & 0xffff);

       sum += (sum >>16) ;

       

       return ~sum;

}

 

你可能感兴趣的:(Linux基础)