假设文件格式定义如下:
size (uint32)
some_list[size] (uint32)
size_indexes (uint32)
other_list[size_indexes] (uint32)
所以有一个列表some_list
包含一些整数,然后还有另一个包含other_list
索引的列表some_list
。
我可以用以下方式解析整个结构:
from construct import *
fmt = Struct(
"size" / Int32ul,
"some_list" / Array(this.size, Int32ul),
"size_indexes" / Int32ul,
"other_list" / Array(this.size_indexes, Int32ul),
)
print(fmt.parse(b"\x02\x00\x00\x00\x23\x42\x23\x42\x13\x37\x13\x37\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"))
给了我
Container:
size = 2
some_list = ListContainer:
1109606947
924006163
size_indexes = 4
other_list = ListContainer:
1
1
0
1
现在我已经解析了fileformat,从中构建python对象的首选方法是什么?例如,我想让它包含实际值,而不是让other_list包含索引。 你会在它周围包裹另一个具有这种能力的物体,例如:
from construct import *
fmt = Struct(
"size" / Int32ul,
"some_list" / Array(this.size, Int32ul),
"size_indexes" / Int32ul,
"other_list" / Array(this.size_indexes, Int32ul),
)
class MyFormat:
def __init__(self, raw):
self._parsed = fmt.parse(raw)
@property
def other_list(self):
for idx in self._parsed.other_list:
yield self._parsed.some_list[idx]
container = MyFormat(b"\x02\x00\x00\x00\x23\x42\x23\x42\x13\x37\x13\x37\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00")
print(list(container.other_list))
打印:
[924006163, 924006163, 1109606947, 924006163]
有更好,更首选的方式吗?
答案 0 :(得分:0)
如果struct
代码不太复杂,则可以使用construct
库提供的类。对于您的情况,我将尝试IfThenElse
和RepeatUntil
类仅使用一个struct
来构建和解析二进制数据。
这里是示例:
import construct
def repeat_handler( x, lst, ctx):
lst[-1] = ctx.some_list[x]
return len(lst) == ctx.size_indexes
my_struct = Struct(
"s" / Int32ul,
"some_list" / Array(this.s, Int32ul),
"size_indexes" / Int32ul,
"other_list" / construct.IfThenElse(this._parsing,
RepeatUntil(repeat_handler, construct.Int32ul),
Array(this.size_indexes, Int32ul))
)
built_struct = my_struct.build(dict(s=2, some_list=[1109606947, 924006163], size_indexes=4, other_list=[1, 1, 0, 1]))
print(built_struct)
parsed_struct = my_struct.parse(built_struct)
print(parsed_struct)
assert parsed_struct.other_list == [924006163, 924006163, 1109606947, 924006163]