Construct - 二进制数据解析器和构建器


MIT
跨平台
Python

软件简介

Construct是一款声明式的二进制数据解析器和构建器。

简而言之,它是对标准模块struct的封装和增强,适用于描述基于二进制数据通信协议的数据结构,可视为二进制数据的Python ORM库。

概述

您不必编写命令式代码来解析一段数据,而是以声明方式定义和描述二进制的数据结构。由于此数据结构不是代码,一方面您可以使用它来将数据解析成Pythonic对象,另一方面,您也可以将pythonict对象构建为二进制数据。

Construct库提供了简单的原子结构(例如各种大小的整数)以及复合的构造,适用于建立日益复杂的分层和顺序结构。Construct拥有基于特征位(bit)和字节(byte)粒度的构建,易于调试和测试,易于扩展的子类系统,以及大量原始构造,使您的工作更轻松:

字段(Field):原始字节或数字类型
结构和序列(Structs and Sequences):将更简单的结构组合到更复杂的结构中
按位(Bitwise):将字节分割为位粒度字段
适配器(Adapter):更改数据的显示方式
数组/范围(Arrays/Ranges):重复构造
元结构(Metaclass):使用上下文(历史)来计算数据的大小
条件(If / Switch):根据上下文分支计算路径
按需(懒惰)解析(Lazy ):只读和解析你需要的东西
指针(Pointers):从这里跳到数据流中

基础用法

Struct例子,与python字典的相对应,Container类类似于字典。

>>> format = Struct(
...     "signature" / Const(b"BMP"),
...     "width" / Int8ub,
...     "height" / Int8ub,
...     "pixels" / Array(this.width * this.height, Byte),
... )
>>> format.build(dict(width=3,height=2,pixels=[7,8,9,11,12,13]))
b'BMP\x03\x02\x07\x08\t\x0b\x0c\r'
>>> format.parse(b'BMP\x03\x02\x07\x08\t\x0b\x0c\r')
Container(signature=b'BMP')(width=3)(height=2)(pixels=[7, 8, 9, 11, 12, 13])

Repeaters例子,与列表相对应,每个元素类型都相同。具体还分为Arrays,Ranges,GreedyRange 和 RepeatUntil
四种子类型。以下是Arrays的例子

>>> Byte[10].parse(b"1234567890")
[49, 50, 51, 52, 53, 54, 55, 56, 57, 48]
>>> Byte[10].build([1,2,3,4,5,6,7,8,9,0])
b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x00'

Sequence例子,与列表相对应,每个元素可以是任意原子或者组合的数据。

>>> format = PascalString(Byte, encoding="utf8") >> GreedyRange(Byte)
>>> format.build([u"lalalaland", [255,1,2]])
b'\nlalalaland\xff\x01\x02'
>>> format.parse(b"\x004361789432197")
['', [52, 51, 54, 49, 55, 56, 57, 52, 51, 50, 49, 57, 55]]

高级用法

4字节存储一个IPv4地址,利用Adapter定义如下:

>>> class IpAddressAdapter(Adapter):
...     def _encode(self, obj, context):
...         return list(map(int, obj.split(".")))
...     def _decode(self, obj, context):
...         return "{0}.{1}.{2}.{3}".format(*obj)
...
>>> IpAddress = IpAddressAdapter(Byte[4])

解析和构建用法如下:

>>> IpAddress.parse(b"\x01\x02\x03\x04")
'1.2.3.4'
>>> IpAddress.build("192.168.2.3")
b'\xc0\xa8\x02\x03'