python实现checksum校验和计算

校验和概念

  • 差错控制编码是为了检查传输中的错误
  • 下面将一个报文的数据部分称为d,报文的冗余部分称为r
  • 发送方根据约定好的差错控制编码关系(关系指出dr之间的关系)和d生成出r;接收方收到报文后取出d和r,判断是否dr符合约定好的关系
    • 如果不符合关系,说明报文传输过程中出错;否则可以认为没错(不考虑残存错误的可能)
  • 校验和checksum就是约定好的差错控制编码关系中的一种,类似还有奇偶校验,CRC循环冗余
    • 校验和适合软件方式实现,计算速度快,接收方检验的效率也高,CRC和奇偶校验适合硬件实现

发送方校验和计算思路

1.计算和

  • 如果d字节数为奇数,末尾加上一个全0字节,使其为偶数
  • 将d以两字节单位拆分;比如8字节的数据,那么可以拆成4组,每组两字节
  • 每组内部,将两个一字节的二进制表示拼接起来
  • 将每组的二进制表示相加,得到整个报文d部分的和(结果应为两字节长度)
    • 如果相加过程中最高位出现了一位进位导致溢出,将进位加在最低位上,此操作称为回卷

2.将和取反,即可得到校验码


示例:UDP计算校验和

  • UDP报文的冗余部分d指的是校验和字段,数据部分d是整个报文除了校验和的字段
    • 之所以把伪头部字段放进d的范围,是为了可以顺带检查伪头部里面的字段是否出错

发送方计算校验和

1.发送方将数据部分d以两字节为单位划分,求和,遇到最高位进位时进行回卷

  • 其中,计算校验和的时候,校验和字段是当作全0去计算的

2.算出和之后取反,将取反后的内容放入校验和字段

  • 此时数据部分d的二进制表示+冗余部分r的二进制表示=二进制全1

接收方验证

1.将收到的报文的d和r取出,验证dr之和是否等于二进制全1

  • r就是校验和字段,d就是除了整个数据包除了校验和的字段
  • 其实不用特意取出,直接计算伪头部和UDP数据报之和即可,因为数据报部分本身就包含了校验和字段呀

python模拟checksum校验和计算

实现代码


# @Time : 2022/12/22 23:07
# @Author : tangxibomb
# @File : simulate checksum.py

def calculate(a,b):#返回回卷后的两十六进制之和的字符串表示
    res=eval(a)+eval(b)
    if res>=0xffff:#回卷
        res=1+eval("0x"+hex(res)[-4:])
    return str(hex(res))

def get0x(a,b):#返回两字符拼接出来的十六进制的字符串表示
    a=hex(ord(a))
    if  a!='\a':
        a+=hex(ord(b))[2:]
    else:#特判是不是字符串长度是否奇数
        a+="0000"
    return a
fd=open('./infile.txt',"r")
words="Hello world."
# words=fd.read()
print("读入的字符串为"+words)
if len(words)&1:#如果字符串长度是奇数,添加一个特殊的字符作为标记
    words=words+'\a'
sum="0"
for idx in range(0,len(words),2):#每两位计算
    tmp=get0x(words[idx],words[idx+1])
    sum=calculate(sum,tmp)
    #print(tmp,sum)

print("该字符串的校验和为"+hex(0xffff-eval(sum)))
posted @   穿过雾的阴霾  阅读(2744)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示