检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。

首先,IP、ICMP、UDP和TCP报文头都有检验和字段,大小都是16bit,算法基本上也是一样的。

    在发送数据时,为了计算数据包的检验和。应该按如下步骤:

    1、把校验和字段设置为0;

    2、把需要校验的数据看成以16位为单位的数子组成,依次进行二进制反码求和;

    3、把得到的结果存入校验和字段中

    在接收数据时,计算数据包的检验和相对简单,按如下步骤:

    1、把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;

    2、检查计算出的校验和的结果是否为0;

    3、如果等于0,说明被整除,校验和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。


校验和算法实现

    代码如下:

    USHORT checksum (USHORT *buffer,int size)

    {

        Unsigned long cksum=0;

        While (size>1)

        {

            Cksum +=*buffer++;

            size -=sizeof(USHORT);

        }

        If (size)

        {

            Cksum +=*(UCHAR *) buffer;

        }

        //将32位转换为16位

        While (cksum>>16)

            Cksum = (cksum>>16) + (cksum & 0xffff);

        Return (USHORT) (~cksum);

    }

#include<stdio.h>
int main()
{
 int a[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
 int i,sum=0;
 for (i=0;i<8;i++)
     sum+=a[i];//将每个数相加
     if(sum>0xff)
     {
         sum+=1;

               sum=~sum;
          }
 sum=sum&0xff; 
 printf("0x%x\n",sum);
}