一、目标
用一个脚本来实现计算特定bin文件的累加和、异或值、CRC16和CRC32值。
二、源码
import os
import struct
import zlib
def crc16_direct(bytestr):
'''
crc16直接计算法
:param bytestr: bytes字符串
:return: int16类型
'''
crc = 0
if len(bytestr) == 0:
return 0
for i in range(len(bytestr)):
R = bytestr[i]
for j in range(8):
if R > 127:
k = 1
else:
k = 0
R = (R << 1) & 0xff
if crc > 0x7fff:
m = 1
else:
m = 0
if k + m == 1:
k = 1
else:
k = 0
crc = (crc << 1) & 0xffff
if k == 1:
crc ^= 0x1021 # 多项式为 0x1021
return crc
if __name__ == '__main__':
# t_path = os.path.abspath('.') #当前绝对路径
# t_path = os.path.join(t_path,'bin') #添加路径
# print(t_path)
dirs = os.listdir('.') #列出当前目录列表
cnt = 0
for i in dirs:
# f_path = os.path.join(t_path,i)
if os.path.isfile(i) and os.path.splitext(i)[1] == '.bin': #是否为文件 分离文件名与扩展名
file = i
cnt += 1
if cnt == 0:
print("未发现bin文件,请将需要计算的Bin文件放在当前文件夹")
elif cnt > 1:
print("存在多个bin文件,无法计算。请保证当前目录下只有一个Bin文件")
elif cnt == 1:
# file = "test.bin"
in_data = input("请输入要计算的类型:\r\n1、累加和\r\n2、异或\r\n3、CRC16\r\n4、CRC32\r\n")
with open(file,"rb") as f:
size = os.path.getsize(file)
if 1 == int(in_data):
sum = 0
for i in range(size):
b_data = f.read(1) # 读文件的一个字节,但是读出来的是十六进制
data = struct.unpack('B', b_data) # B的函数是将C的uchar 类型转换为python中的integer类型
sum += data[0] # 为tuple类型,所以用[0]将数字取出
sum = sum & 0xffff
print("累加和结果:0x%.4x (%d)" %(sum,sum))
elif 2 == int(in_data):
xor = 0
for i in range(size):
b_data = f.read(1) # 读文件的一个字节,但是读出来的是十六进制
data = struct.unpack('B', b_data) # B的函数是将C的uchar 类型转换为python中的integer类型
xor ^= data[0] # 为tuple类型,所以用[0]将数字取出
xor = xor & 0xff
print("异或值:0x%.2x (%d)" %(xor,xor))
elif 3 == int(in_data):
crc16_value = crc16_direct(f.read(size))
print(f"CRC16值:0x{hex(crc16_value)} {crc16_value}")
elif 4 == int(in_data):
res = 0
res = zlib.crc32(f.read(size), res) #bytes类型内容,res初始值
print("CRC32值:0x%.8x (%d)" %(res,res))
else:
print("未知类型!!!")
input("请输入任意字符结束")
三、结果
通过输入1-4来选择不同的计算结果。最终的计算结果与网络上的工具计算结果相同。
工具计算结果
累加和算法结果
异或结果
CRC16结果
CRC32结果