checksum校验

来源:互联网 发布:知乎源代码下载 编辑:程序博客网 时间:2024/05/17 23:05

原理

        P/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,采用的都是将数据流视为16位整数流进行重复叠加计算。为了计算检验和,首先把检验和字段置为0。然后,对有效数据范围内中每个16位进行二进制反码求和,结果存在检验和字段中,如果数据长度为奇数则补一字节0。当收到数据后,同样对有效数据范围中每个16位数进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全0或全1(具体看实现了,本质一样; 校验时可能返回~checksum) 。如果结果不是全0或全1,那么表示数据错误。

例子:

[cpp] view plain copy
  1. #include <stdio.h>  
  2.   
  3. unsigned short checksum(unsigned short *pdate, int size)  
  4. {  
  5.     unsigned int sum=0;  
  6.     while (size>1)  
  7.     {     
  8.         sum += *pdate;  
  9.         pdate++;  
  10.         size -= sizeof(short);  
  11.     }     
  12.       
  13.     if (size)  
  14.         sum += *(unsigned char*)pdate;  
  15.       
  16.     while(sum>>16)  
  17.     {     
  18.         sum = (sum & 0xffff) + (sum>>16);  
  19.     }     
  20.   
  21.     return ~sum;  
  22. }  
  23.   
  24. int main(void)  
  25. {  
  26.     unsigned short checksum_code=0;  
  27.     unsigned short date[] = {0,0x4500, 0x0029, 0x44f1,0x4000, 0x8006, 0xc0a8, 0x01ae, 0x4a7d, 0x477d};//date[0]存放校验码  
  28.     unsigned short check_res=0;  
  29.   
  30.     checksum_code = checksum((unsigned short*)date, sizeof(date));//产生校验码  
  31.     date[0] = checksum_code;  
  32.     printf("generate:%x\n", checksum_code);  
  33.   
  34.     check_res= checksum((unsigned short*)date, sizeof(date));//校验结果  
  35.     printf("check result:%x\n", check_res);  
  36.     return 0;  
  37. }  

编译运行:

原创粉丝点击