为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Python Numpy 解析包含 BCD(二进制编码的十进制)值的二进制文件

使用 Python Numpy 解析包含 BCD(二进制编码的十进制)值的二进制文件

Qyouu 2021-08-24 15:13:17
我有一个二进制文件,其中一些字段编码为 BCD(二进制编码的十进制)。示例如下。14 75 26 58 87 7F(十六进制格式的原始字节)。我正在使用 (np.void, 6) 从二进制文件读取和转换,下面是我得到的输出。b'\x14\x75\x26\x58\x87\x7F'但我想得到输出为 '14752658877',没有使用 numpy 的填充字符 'F'。下面是代码: with open (filename, "rb") as f:    while True:        chunk = f.read(chunksize)        if (chunk):            dt = np.dtype([('a','b'), ('b', '>i4'), ('c', 'S15'),('d', np.str, 7),                                   ('e', 'S7'), ('f', np.void, 6)])            x = np.frombuffer (chunk, dtype=dt)            print (x)        else:            break此外,输入文件包含许多固定长度的二进制记录。使用 numpy.txt 将其转换并存储为 ascii 文件的有效方法是什么?
查看完整描述

1 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

我不知道 numpy 是否可以以某种方式加速这一点,但是可以快速构建一个专门的函数:


fastDict = {16*(i//10)+(i%10):i for i in range(100)}


def bcdToInteger(bcd):

    result = 0

    while bcd and bcd[0] in fastDict:

        result *= 100

        result += fastDict[bcd[0]]

        bcd = bcd[1:]

    if bcd and bcd[0] & 0xf0 <= 0x90:

        result *= 10

        result += bcd[0]>>4

        if bcd[0] & 0xf <= 9:

            result *= 10

            result += bcd[0] & 0x0f

    return result


>>> print (bcdToInteger(b'\x14\x75\x26\x58\x87\x7F'))  # your sequence

14752658877

>>> print (bcdToInteger(b'\x12\x34\xA0'))   # first invalid nibble ends

1234

>>> print (bcdToInteger(b'\x00\x00\x99'))   # and so does an end of string

99

>>> print (bcdToInteger(b'\x1F'))           # a single nibble value

1

只要您继续提供有效的 BCD 字节,它就会将结果乘以 100 并添加两个新数字。只有最后一个字节需要进一步检查:如果最高半字节有效,则到目前为止的结果乘以 10,然后添加该半字节。如果最低半字节也有效,则重复此操作。


这fastDict是为了加快速度。这是从字节返回正确的值全部100六角一本字典00,以99使实际计算的数量尽可能小。你可以不用字典,但这意味着你必须在if块中对每个字节进行比较和计算。


查看完整回答
反对 回复 2021-08-24
  • 1 回答
  • 0 关注
  • 334 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信