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)))
有帮助的话可以点个赞,我会很开心的~

浙公网安备 33010602011771号