校验和算法

首先,IP、ICMP、UDP和TCP报文头部都有校验和字段,大小都是16bit,算法也基本一样:
在发送数据时,为了计算数据包的校验和。应该按如下步骤:
(1)把校验和字段置为0;
(2)把需校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;
(3)把得到的结果存入校验和字段中。
在接收数据时,计算数据包的校验和相对简单,按如下步骤:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;
(2)检查计算出的校验和的结果是否为0;
(3)如果等于0,说明被整除,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。
虽然上面四种报文的校验和算法一样,但在作用范围存在不同:IP校验和只校验20字节的IP报头;而ICMP校验和覆盖整个报文(ICMP报头+ICMP数据);UDP和TCP校验和不仅覆盖整个报文,而且还有12字节的IP伪首部,包括源IP地址(4字节)、目的IP地址(4字节)、协议(2字节,第一字节补0)和TCP/UDP包长(2字节)。另外UDP、TCP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(注意,填充字节只是为了计算校验和,可以不被传送)。
这里还要提一点,UDP的校验和是可选的,当校验和字段为0时,表明该UDP报文未使用校验和,接收方就不需要校验和检查了!那如果UDP校验和的计算结果是0时怎么办呢?书上有这么一句话:“如果校验和的计算结果为0,则存入的值为全1(65535),这在二进制反码计算中是等效的。”
讲了这么多,那这个校验和到底是怎么算的呢?


什么是二进制反码求和(1的补码)

对一个无符号的数,先求其反码,然后从低位到高位,按位相加,有溢出则向高位进1(跟一般的二进制加法规则一样),若最高位有进位,则向最低位进1。
首先这里的反码好像跟我们以前学的有符号数的反码不一样(即正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各位取反),这里不分正负数,直接每个位都取反!
上面加粗的那句是跟我们一般的加法规则不太一样的地方:最高位有进位,则向最低位进1。确实有些疑惑,为什么要这样做呢?仔细分析一下(为了方便说明,以 4bit二进制反码求和举例),上面的这种操作,使得在发生加法进位溢出时,溢出的值并不是10000,而是1111。也即是当相加结果满1111时溢出,这样也可以说明为什么0000和1111都表示0了(你同样可以发现,任何数与这两个数做二进制反码求和运算结果都是原数,这恰好符合数0的加法意义)。


下面再举例两种二进制反码求和的运算:
原码加法运算 反码加法运算
3(0011)+ 5(0101)= 8(1000) 3(1100)+ 5(1010)= 8(0111)
8(1000)+ 9(1001)= 1(0001) 8(0111)+ 9(0110)= 2(1101)
从上面两个例子可以看出,当加法未发生溢出时,原码与反码加法运算结果一样;当有溢出时,结果就不一样了,原码是满10000溢出,而反码是满1111溢出,所以相差正好是1。举例只是为了形象地观察二进制反码求和的运算规则,至于为什么要定义这样的规则以及该运算规则还存在其它什么特性,可能就需要涉及代数理论的东西的了。
另外关于二进制反码求和运算需要说明的一点是,先取反后相加与先相加后取反,得到的结果是一样的!(事实上我们的编程算法里,几乎都是先相加后取反。)

1的补码(相加和补取)
猜测是计算机相关语言.请参考这两段文字:
It is the 1’s complement of the 1’s complement sum of all the 16-bit words in the TCP header and data.
这是关于TCP头部校验和字段(checksum field)的说明.句中的complement意思为“补码”.对于学习计算机科学的人来说,补码不算什么新鲜,现在新鲜的是这篇英语文章出现的是“1’s complement” ,翻译出来应该是“1的补码”,对于这个笔者以前也没有碰到过,到网上查吧!网上查询的结果,“1’s complement”关键字出现的不少,但都是英文关键字,没有对应的中文翻译与解释,所以先看英语的,最后自己做解释吧.
补码:补码是计算机中二进制数表达负数的办法,这样可以在计算机中把两个数的减法变成加法.补码形式有1的补码和2的补码,其中1的补码用在IP、TCP的校验和中;平时学生在计算机科学中学习的补码是2的补码(即正数的补码和原码相同,负数补码按原码相应的正数按位取反再加1).
只是平时中文教材及中文翻译的书中,对此并不多加解释,一律翻译作补码.比如《Computer Network》(Andrew S.Tanenbaum )在中国的翻译版《计算机网络》(清华大学出版社)对于TCP头部的校验和是这样翻译的:
(原文)The checksum algorithm is simply to add up all the 16-bit words in one's complement and then to take the one's complement of the sum.
(译文)校验和的算法是简单地将所有16位字以补码形式相加,然后再对相加和取补.
仔细对比一下本文最上部笔者所碰到的句子,和刚才这个句子意思是一样的.这个没有注明是1的补码,翻译时只是以“补码”说明,也许译者并不想在这里多费口舌,因为说明1的补码实在是一个比较麻烦的事情,笔者在这里翻译时还是把“1的补码”给翻译出来了,以让大家注意这个1的补码并不是平常学的那个2的补码.
笔者只是在此讨论翻译,不是在讨论补码.1的补码较复杂,如果有兴趣,可以上网查找 RFC1071 ,这是TCP校验和权威的官方说明.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值