天天看点

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果

一、目标

用一个脚本来实现计算特定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来选择不同的计算结果。最终的计算结果与网络上的工具计算结果相同。

工具计算结果

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果

累加和算法结果

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果

异或结果

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果

CRC16结果

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果

CRC32结果

Python脚本实例-计算bin文件校验值(附源码)一、目标二、源码三、结果