checksum的作用,checksum值

  checksum的作用,checksum值

  如何解决网络报文中的校验和?最近在学习计算机网络中,有TCP、UDP、IP、ICMP等各种协议。在传输层和网络层,在这些消息中有一个公共字段3354校验和。接下来我将从什么是校验和、校验与如何计算、校验与计算实例、python代码计算校验以及这几个部分来详细介绍。

  什么是检验和?校验和是存在于各类报文中的一个字段,目的是验证报文在网络传输过程中的完整性(链路传输过程中部分数据可能出现0-1数据翻转,导致报文错误)。所以在消息的发送方,会根据消息中的报头或数据计算一个校验和(IP消息校验和只计算报头,ICMP消息同时计算报头和数据),然后一旦接收方收到相应的消息,接收方也会对消息的报头或数据进行一次检查和计算。如果接收方计算的校验和与发送方发送的校验和不同,那么对不起,接收方认为消息在传输过程中出现了错误,所以会将其丢弃。

  算法从开始对待测部分求和,每16位加一位(如果最后还剩8位,就把这8位加到最后),这样最后计算出来的和进行一个逆运算,就是测试和。

  注意:如果在求和过程中遇到任何溢出,它将被回滚(即加回最低位)。

  例子

  IP领域看完还在发呆?没关系。这里以IP报文为例介绍更多细节。首先回顾一下IP报文的各个字段的信息,如下图所示。如果看到这个,有些字段忘了它的意思,就在百度上回忆一下。这里不多说了。

  IP报头检查和示例现在假设有一个IP消息报头,如下所示(全部是十六进制数字):

  4500 003 c 1c 46 4000 4006 B1 E6 ac10 0a 63 ac10 0a0c

  好了,我们把这条消息的字段一个一个匹配起来。

  4——对应于IP报头的前8位,4是版本字段,表示IPV4,5是报头长度字段。但是注意,报头长度是每4个字节一个单位,所以这里是5*4=20个字节(这也说明IP报文报头的option字段和padding字段是没用的)。00 ——对应业务类型(TOS,业务类型)字段,00表示正常运行,003c3354对应总长度字段,表示IP报文头加上数据段总共60字节(即数据段占用40字节)1C46 ——对应报文标识符字段4000 ——对应标志和分片偏移量字段,其中标志字段占用3位,分片偏移量占用13位。40 ——对应于TTL字段(生存时间)。表示该报文可以经过40跳的上层协议代码)06 ——对应IP报文封装,这里是6,表示是TCP报文B1 E63354,是发送方要找的测试和IP报文目的IP地址发送方对应IP报文AC100C3354对应的源IP地址AC100A63 3354好吧!最后,计算可以开始了。 )

  注意:在计算测试和字段之前,我们将测试和的所有16位设置为0。

  现在我们将所有十六进制数转换成二进制数,如下所示:

  400-01000100000000000003c-000000000000011100100100001104000-01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

  400-010001000000000003c-00000000111100453 c-010001010011100//第一个计算结果453c-0100010101011100//最后16位数字相加1c 46-00011100010001106182-01110000000000111根据回滚规则,将溢出位添加到最后18d 98-11000110110008 d99-100011011011001//并进行类似的16位添加。我就不重复8d 99-1000110110010 a63-0001010011001197 fc-100101111111100 97FC-100101111111111111100 ac10-10101101100000000010000000000000000140 c-10101010101010101010101!还求个反码,别忘了~ ~

  4e 9-01001100011001 b1e6-1011001111100110//校验和准备好了,这样我们就可以把b1e 6的校验和放入IP报文的校验和字段,验证完成。

  接收端接收端相对简单。每16位加所有二进制位,最后得到一个补码(也是溢出和回滚)。如果结果都是1,则稳定,没有误差;只要有一位是0,就说明有错误。

  Python实现看完上面的,你一定知道怎么计算了,但是代码实现可能还是有点难度。在此,我要感谢《JamesF》的作者。Kurose —— 《计算机网络:自顶向下方法》获取该书附带的资源和代码。下面的代码来自书中编程实验的ICMPping程序。

  我已经注释了具体的代码分析,你可以看看。

  def checksum(str):csum=0 # checksum(一个32位的十进制数,因为每16位加在一起就可能发生进位(即溢出),这些溢出会被回滚)#奇偶控制。如果字节的总长度是奇数,请确保最后一个字节应该单独相加(检查总和时每16位加1)。count to=(len(str)//2)* 2 count=0 while count to:# ord()函数返回一个字符的ASCII码#取两个字节,第二个字节放在16位的高位,第一个字节放在16位的位置this val=(str[count 1]8)str[count]csum=csum this val #这里与0xffffffff的and运算主要是为了保留每次运算时可能出现的16位溢出,#这样就可以将溢出位(即进位)保存到sum的高16位,csum=csum0x fffffff count=count 2 #,并向后移动两个字节。也就是准备对接下来的16位求和#如果计数到len (str)真的还有一个字节的话:csum=CSUMSTR [len (str)-1]。Decode () CSUM=CSUM0xffffffff #将CSUM的高16位溢出回卷中,将csum=(csum16) (csum0xffff)加到低16位#如果仍然发生溢出,则运算csum=csum (csum 16)#求反答案=~ csumanswer=答案0xffff #这里转换的是字节顺序。因为网络端序是big-endian模式answer=answer 8 (answer 80xff00)返回答案参考RFC 1071计算机网络一种自上而下的方法:jamesf.kurosehow如何计算IP头校验和(附示例)

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: