starstruct允许简单的二进制流打包/解包
StarStruct的Python项目详细描述
开始结构
提供二进制数据的一致打包和解包的包
开始
要求
- Python3.5+
安装
starstruct可以与pip一起安装:
$ pip install starstruct
或者直接从源代码:
$ git clone https://github.com/sprout42/StarStruct.git $ cd StarStruct $ python setup.py install
基本用法
安装后,可以导入包:
$ python >>> import starstruct >>> starstruct.__version__
下面是该软件包的一个示例
importenum# Import the packagefromstarstructimportModefromstarstruct.messageimportMessage# A custom Enum you might be usingclassMyEnum(enum.Enum):my_custom_data_type=0x0my_other_data_type=0x1final_data_type=0x2SizeOfData=Message('Data',[('pad','8x')],Mode.Big)AnotherDataSize=Message('Data',[('status','H'),('pad','6x'),],Mode.Big)# Create your MessageMyMessage=Message('message_name',[('an_important_integer','i'),# Pack it into the size of a struct integer('ten_long_string','10s'),# Pack it like 10 consecutive characters('a_fixed_point_number','F','i',4),# Pack it in the size of an integer, but with four bits of precision# as a floating point number('union_identifier','B',MyEnum),('like_a_c_union',{MyEnum.my_custom_data_type:SizeOfData,# These sizes should usually all be the same,MyEnum.my_other_data_type:AnotherDataSize,# but they can be of different styles!MyEnum.final_data_type:SizeOfData,},'union_identifier'),# Choose which type of thing based on union_identifier],Mode.Big)# Pack it with big endianess# Now you can use a dictionary to make your messagesdata_1={'an_important_integer':42,'ten_long_string':'wow! stuff','a_fixed_point_number':'1.25','union_identifier':MyEnum.my_other_data_type,'like_a_c_union':{'status':1}}named_tuple_version=MyMessage.make(data_1)print(named_tuple_version.an_important_integer)# 42print(named_tuple_version.a_fixed_point_number)# b'\x00\x00\x00\x14'packed_message=MyMessage.pack(data_1)print(packed_message)# b'\x00\x00\x00*wow! stuff\x00\x00\x00\x14\x01\x00\x01\x00\x00\x00\x00\x00\x00'unpacked_message=MyMessage.unpack(packed_message)print(unpacked_message.an_important_integer)# 42print(unpacked_message.a_fixed_point_number)# 1.25# -----------------------# Variable sized messages# -----------------------RepeatedMessage=Message('Repeated',[('x','B'),('y','H'),])VariableMessage=Message('variable_message',[('length_in_objects','H','message_data'),# length field, in terms of message objects('message_data',RepeatedMessage,'length_in_objects'),# variable message length data(b'length_in_bytes','B','bytes_data'),# length field, in terms of packed bytes('bytes_data',RepeatedMessage,b'length_in_bytes'),# variable bytes length data('repeated_data',RepeatedMessage,3),# fixed length repeated message],Mode.Little)variable_data={'length_in_objects':2,# Two objects long'message_data':[{'x':5,'y':6},# Object number 1{'x':9,'y':1},# Object number 2],'length_in_bytes':12,# Each object is 3 bytes long, so 4 objects'bytes_data':[{'x':0,'y':8},# Object number 1, bytes 0 - 2{'x':1,'y':9},# Object number 2, bytes 3 - 5{'x':2,'y':0},# Object number 3, bytes 6 - 8{'x':6,'y':2},# Object number 4, bytes 9 - 11],'repeated_data':[# No length field specified required. Just the messages{'x':1,'y':9},{'x':1,'y':9},{'x':0,'y':5},],}named_tuple_version=VariableMessage.make(variable_data)print(named_tuple_version.length_in_objects)# 2print(named_tuple_version.length_in_bytes)# 12print(named_tuple_version.bytes_data)# [Repeated(x=0, y=8),# Repeated(x=1, y=9),# Repeated(x=2, y=0),# Repeated(x=6, y=2)]packed_message=VariableMessage.pack(**variable_data)print(packed_message)# b' x02 x00 x05 x06 x00 t x01 x00 \# x0c x00 x08 x00 x01 t x00 x02 \# x00 x00 x06 x02 x00 x01 t x00 \# x01 t x00 x00 x05 x00'unpacked_message=VariableMessage.unpack(packed_message)print(unpacked_mesage.length_in_objects)# 2print(unpacked_mesage.length_in_bytes)# 12print(unpacked_mesage.bytes_data)# [Repeated(x=0, y=8),# Repeated(x=1, y=9),# Repeated(x=2, y=0),# Repeated(x=6, y=2)]
修订历史
0.0.0(yyyy/mm/dd)
- 待定