当前位置:文档之家› 校验和算法

校验和算法

校验和算法
IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的。

今儿以IP 数据包为例来讲解一下校验和算法。

在IP数据包发送端,首先将校验和字段置为0,然后将IP数据包头按16比特分成多个单元,如果包头长度不是16比特的倍数,则用0比特填充到16 比特的倍数,其次对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段,最后发送数据。

在IP数据包接收端, 首先将IP包头按16比特分成多个单元,如果包头长度不是16比特的倍数,则用0比特填充到16比特的倍数,其次对各个单元采用反码加法运算,检查得到的和是否符合全是1(有的实现可能对得到的和取反码,然后判断最终的值是否为0),如果符合全是1(取反码后是0),则进行数据包的下一步处理,如果不符合,则丢弃该数据包。

在这里大家要注意,反码和是采用高位溢出加到低位上。

接下来以一张从网上找的一张IP数据包头图片来加以说明以上的算法。

大家应该记得一个公式,即两数据的反码和等于两数据和的反码,把它推广到n个数据同样适用,公式:~[X]+~[Y]=~[X+Y]
从这张图片可以看出它的校验和是0x618D,现在我们来用它来模拟我
们的发送端和接收端。

发送端:
步骤如下:
首先,将checksum字段设为0,那么将得到IP数据包头的分段信息如下
1. 0x4500
2. 0x0029
3. 0x44F1
4. 0x4000
5. 0x8006
6. 0x0000 ------->这个为Header Checksum的值,我们前面将其
重置为0了
7. 0xC0A8
8. 0x01AE
9. 0x4A7D
+10. 0x477D
结果为:0x29E70
注意要将溢出位加到低位,即0x29E70的溢出位为高位2,将它加到低位上,即0x9E70+0x2=0x9E72
0x9E72二进制为:1001 1110 0111 0010
反码为:0110 0001 1000 1101
0110 0001 1000 1101的16进制为:0x618D(这就是我们的校验和) 接收端:
当我们收到该数据包时,它的分段信息将是如下信息:
1. 0x4500
2. 0x0029
3. 0x44F1
4. 0x4000
5. 0x8006
6. 0x618D ------->这个为Header Checksum的值
7. 0xC0A8
8. 0x01AE
9. 0x4A7D
+10. 0x477D
结果为:0x2FFFD
该数值的溢出位为高位2,把它加到底位D上,即0xFFFD+0x2=0xFFFF 0xFFFF二进制为:1111 1111 1111 1111
1111 1111 1111 1111反码为:0。

相关主题