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

Python:从二进制数据中解压结构数组的最佳方法是什么

Python:从二进制数据中解压结构数组的最佳方法是什么

婷婷同学_ 2023-01-04 16:14:32
我正在解析二进制文件格式(OpenType 字体文件)。该格式是许多不同结构类型的复杂树,但一个重复出现的模式是具有特定格式的记录数组。我已经编写struct.unpack了用于一次获取一条记录的代码。但我想知道是否有一种方法可以解析整个记录数组?以下是一种特定记录数组的解压缩结果示例:[{'glyphID': 288, 'paletteIndex': 0}, {'glyphID': 289, 'paletteIndex': 1}, {'glyphID': 518, 'paletteIndex': 0}, ...]    list这就是我目前正在做的事情:我创建了一个通用函数来解压缩任意记录数组(在任何给定调用中的记录格式一致)。def tryReadRecordsArrayFromBuffer(buffer, numRecords, format, fieldNames):    recordLength = struct.calcsize(format)    array = []    index = 0    for i in range(numRecords):        record = {}        vals = struct.unpack(format, buffer[index : index + recordLength])        for k, v in zip(fieldNames, vals):            record[k] = v        array.append(record)        index += recordLength    return array该buffer参数是一个字节序列,大小至少为数组的大小,第一个记录在序列的开头被解包。根据正在读取的记录数组的类型,format参数是格式字符串。struct在一种情况下,格式字符串可能是">3H";在另一种情况下,它可能是">4s2H";等。对于上面的结果示例,它是">2H"。该fieldNames参数是给定记录类型中字段名称的字符串序列。对于上面的结果示例,这是("glyphID", "paletteIndex").因此,我正在遍历缓冲区(字节序列数据),获取顺序切片并一次一个地解压缩记录,为每条记录创建一个字典并将它们附加到array列表中。有没有更好的方法来做到这一点,比如unpack某些模块中的方法允许将格式定义为结构数组并立即解压整个 shebang?
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

看看 kaitai - https://kaitai.io/,这是一个用于跨多种语言解析二进制文件的库,具有以独立于语言的方式定义文件格式的框架。

它能够在文件格式中定义条件,并根据需要调整解析。虽然学习曲线并非立即微不足道,但也不是太难。


假设您想自己做而不是使用外部库,则需要考虑一些可以提高性能/代码的事情:

  1. 使用struct.unpack_from(format, buffer, offset=0)而不是当前方法,因为buffer[index : index + recordLength]可能会创建新对象并复制不需要的内存

  2. 如果你想解包相同格式的数组,你可以进一步改进它struct.iter_unpack(format, buffer),然后迭代结果:

import itertools

import struct


def tryReadRecordsArrayFromBuffer(buffer, numRecords, format, fieldNames):

    unpack_iter = struct.iter_unpack(buffer, format)

    return [

        # I like this better than dict(zip(...)) but you can also do that

        {k: v for k, v in zip(fieldNames, vals)}

        # We use `islice` to only take the first numRecords values

        for vals in itertools.islice(unpack_iter, numRecords)

    ]


查看完整回答
反对 回复 2023-01-04
  • 1 回答
  • 0 关注
  • 92 浏览
慕课专栏
更多

添加回答

举报

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