# IP数据包的校验和算法

1.     把校验和字段清零；

2.     按两个字节的十六进制数进行反码求和

//by zc 5/29/2016
#include <iostream>
#include<bits/stdc++.h>
using namespace std;

unsigned short buffer[2][20]
{
{
0x4500,
0x0031,
0x89f5,
0x0000,
0x6e06,
0x0000,		// checksum
0xdeb7,
0x455d,
0xc0a8,
0x00dc
},
{
0x4500,
0x003c,
0x0000,
0x0000,
0x4001,
0x0000,		// checksum
0xc0a8,
0x0125,
0xda3c,
0x0682
}
};

unsigned short CheckSum(unsigned short *buffer,int _size)
{
unsigned long cksum=0;//用unsigned long的4字节保证不会溢出

while (_size>1)//求和
{
cksum+=*buffer++;
_size-=2;
}

if(_size)//处理输入的数据为奇数字节的情况
cksum+=*(unsigned char*)buffer;//由于只有一字节，转换成unsigned char处理

while(cksum>>16)//如果存在高位溢出的情况，则将高位加到低位
cksum=(cksum>>16)+(cksum&0xffff);

return (unsigned short)(~cksum);//返回反码
}

int main()
{
for(int i=0;i<2;i++)
{
cout<<hex<<CheckSum(buffer[i],sizeof(buffer[i]))<<endl;//传输前计算校验和
buffer[i][5]=CheckSum(buffer[i],sizeof(buffer[i]));//填入校验和
cout<<hex<<CheckSum(buffer[i],sizeof(buffer[i]))<<endl;//接收时计算校验和
}
}


http://www.cnblogs.com/fhefh/archive/2011/10/18/2216885.html

http://blog.csdn.net/chenlong12580/article/details/7354037

http://blog.csdn.net/immember/article/details/41244507

http://blog.chinaunix.net/uid-26527046-id-3695653.html

05-16 6975

11-25 742

10-27 1.4万

03-14 8910

11-15 2935

12-23 1.8万

05-13 2340

12-19 499

09-09 5.1万

11-14 6194