Python 计算 UDP 检验和

参考链接

Python 计算 UDP 检验和

目录

1. 前言
2. 分析
3. 代码
4. 结果
5. 总结

一、前言

IP 头部校验、UDP 校验与 TCP 校验方法基本一致,这里用参考链接一里面的 UDP 数据包来了解 UDP 检验和的计算。

二、分析

在这里插入图片描述
UDP 计算检验和的方法和计算 IP 数据报首部检验和的方法相似。但不同的是:IP数据包的检验和只检验 IP 数据报的首部,但 UDP 的检验和是把首部和数据部分一起检验。

  1. 先得出 UDP 校验和部分
    UDP 校验和部分 = 伪首部(12 字节) + UDP 首部(8 字节)+ 数据(n 个字节)
    伪首部(12 字节) = 源 IP 地址(4 字节) + 目的 IP 地址(4 字节)+ 0x00(1 字节)+ 协议号(1 字节)+ UDP 长度(2 字节)
    将 UDP 校验和部分拼出来后,将检验和置为 0 。将校验部分看成许多 16位的字串接起来的。若 UDP 用户数据部分不是偶数个字节,则要填充一个全 0 字节(但此字节不发送)。
  2. 二进制反码计算 出这些 16 位字的和
  3. 当无差错时,其结果应为全 1。否则就表明有差错出现,接收方就应该丢弃这个 UDP 数据报(也可以上交给应用层,但附上出现了差错的警告)

参考链接:

三、代码
class Udp_check():
    def __init__(self, IP_content):
        self.IP_content =  IP_content
        self.IP_header_len = 20 #IP头部20字节
        self.check_content = []  #UDP校验和部分
        # UDP校验和部分 = UDP伪首部 + UDP内容(UDP首部 + UDP数据部分)
        
    def add_udp_pseudo_header_content(self):
        # UDP伪首部 = 源IP地址 + 目的IP地址 + 0x00 +协议字段 + UDP长度
        
        #IP源地址为IP报文的13、14、15、16字节,即伪首部的源IP地址字段
        self.check_content.append(self.IP_content[12])
        self.check_content.append(self.IP_content[13])
        self.check_content.append(self.IP_content[14])
        self.check_content.append(self.IP_content[15])

        #IP目的地址为IP报文的17、18、19、20字节,即伪首部的目的IP地址字段
        self.check_content.append(self.IP_content[16])
        self.check_content.append(self.IP_content[17])
        self.check_content.append(self.IP_content[18])
        self.check_content.append(self.IP_content[19])

        #UDP伪首部的第三个字段,为0x00
        self.check_content.append(0x00)
        
        #协议类型是IP报文的第10字节,即伪首部的协议类型字段
        self.check_content.append(self.IP_content[9])

        #UDP数据长度是UDP报文中的第5、6字节,伪首部的长度字段

        self.check_content.append(self.IP_content[self.IP_header_len + 4])
        self.check_content.append(self.IP_content[self.IP_header_len + 5])

    def add_udp_content(self):
        #udp内容的长度
        udp_content_len = len(self.IP_content) - self.IP_header_len
        #往校验部分添加udp内容
        for i in range(udp_content_len):
            self.check_content.append(self.IP_content[self.IP_header_len + i])

    def set_and_fill_zero(self):
        self.check_content[18] = 0    #把原来的校验和设置为0
        self.check_content[19] = 0

        if len(self.check_content) % 2 == 1: #整个报文长度为奇数需要补充0
            self.check_content.append(0x00)


    def check_process(self):
        data_sum = []
        
        #先需要将前后二个数合并成16位长度的16进制的数
        for num in range(0, len(self.check_content), 2):
            #如果转换为16进制后只有1位需要高位补0操作,用zfill方法
            part1 = str(hex(self.check_content[num]))[2:].zfill(2)
            part2 = str(hex(self.check_content[num+1]))[2:].zfill(2)
            part_all = part1 + part2
            data_sum.append(int(part_all, 16))
##        print(data_sum)

        sum_total = sum(data_sum) #计算所有数的和
        sum_total_hex = str(hex(sum_total))[2:] #16进制化
        sum_total_hex_len = len(sum_total_hex) #取得字节长度

        if sum_total_hex_len > 4: #求和的结果大于2个[字节16位]的话,分割成2个2字节16位数
            part1 = int(sum_total_hex[: sum_total_hex_len - 4], 16) #分割第一、二字节的十六进制数字,转换为10进制
            part2 = int(sum_total_hex[sum_total_hex_len - 4: ], 16) #分割第三、四字节的十六进制数字,转换为10进制
            part_all = part1 + part2
        else:
            part_all = sum_total

        last_check_sum = str(hex(65535 - part_all))[2:]    #二个字节的十六进制数之和取反
        return sum_total_hex, last_check_sum
    
            
    def run(self):
        self.add_udp_pseudo_header_content()
        self.add_udp_content()
        check1 = str(hex(self.check_content[18]))[2:]
        check2 = str(hex(self.check_content[19]))[2:]
                  
        print("检验和:0x{0}{1}".format(check1, check2))

        self.set_and_fill_zero()
        print('需要计算的UDP校验和内容为:{}'.format((self.check_content)))
        ## UDP校验和部分准备完成

        sum_total_hex, last_check_sum = self.check_process()
        print("sum_total_hex: 0x{}".format(sum_total_hex))
        print("检验和:0x{0}".format(last_check_sum))

        temp = hex((int(sum_total_hex, 16) >> 16) + (int(s
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值