猿问

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

我有一个二进制文件,其中一些字段编码为 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 文件的有效方法是什么?


Qyouu
浏览 335回答 1
1回答

开满天机

我不知道 numpy 是否可以以某种方式加速这一点,但是可以快速构建一个专门的函数:fastDict = {16*(i//10)+(i%10):i for i in range(100)}def bcdToInteger(bcd):&nbsp; &nbsp; result = 0&nbsp; &nbsp; while bcd and bcd[0] in fastDict:&nbsp; &nbsp; &nbsp; &nbsp; result *= 100&nbsp; &nbsp; &nbsp; &nbsp; result += fastDict[bcd[0]]&nbsp; &nbsp; &nbsp; &nbsp; bcd = bcd[1:]&nbsp; &nbsp; if bcd and bcd[0] & 0xf0 <= 0x90:&nbsp; &nbsp; &nbsp; &nbsp; result *= 10&nbsp; &nbsp; &nbsp; &nbsp; result += bcd[0]>>4&nbsp; &nbsp; &nbsp; &nbsp; if bcd[0] & 0xf <= 9:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result *= 10&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += bcd[0] & 0x0f&nbsp; &nbsp; return result>>> print (bcdToInteger(b'\x14\x75\x26\x58\x87\x7F'))&nbsp; # your sequence14752658877>>> print (bcdToInteger(b'\x12\x34\xA0'))&nbsp; &nbsp;# first invalid nibble ends1234>>> print (bcdToInteger(b'\x00\x00\x99'))&nbsp; &nbsp;# and so does an end of string99>>> print (bcdToInteger(b'\x1F'))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# a single nibble value1只要您继续提供有效的 BCD 字节,它就会将结果乘以 100 并添加两个新数字。只有最后一个字节需要进一步检查:如果最高半字节有效,则到目前为止的结果乘以 10,然后添加该半字节。如果最低半字节也有效,则重复此操作。这fastDict是为了加快速度。这是从字节返回正确的值全部100六角一本字典00,以99使实际计算的数量尽可能小。你可以不用字典,但这意味着你必须在if块中对每个字节进行比较和计算。
随时随地看视频慕课网APP

相关分类

Python
我要回答