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'