我从来没有在python中处理过多个数据类型的二进制文件。我希望我能得到一些方向。二进制文件包含以下数据类型:
的字符串
字节
UInt8 -Size in bytes:1-8位无符号整数。
UInt16 -Size in bytes:2- Little-endian编码的16位无符号整数
UInt32 -Size in bytes:4- Little-endian编码的32位无符号整数
UInt64 -Size in bytes:8- Little-endian编码的64位无符号整数。
我一直无法做到的是正确解码我的数据。数据包含一种通用消息格式,用作提供一个或多个更高级别消息的包装器。我在下面提供了这个包装器中包含的字段名称。
在此消息中我可以:
长度 - 偏移0 - 尺寸2 - 类型UInt16
消息计数 - 偏移2 - 大小1-类型UInt8
ID - 偏移3 - 大小1 - 类型字节
顺序 - 偏移4 - 大小4 - 类型UInt32
有效负载 - 偏移8
如果长度指定了公共消息的长度,则消息计数会告知有效负载中将开始有多少更高级别的消息。
更高级别的消息从Payload开始,具有以下特征
消息长度 - 0 - 大小1 - 类型UInt8
消息类型 - 偏移1 - 大小1 - 类型字节
一旦我能够弄清楚每个更高级别消息中的消息类型是什么,其余的都是微不足道的。我一直在尝试创建一个类BinaryReader来为我做这个,我还没有成功使用struct.unpack。
编辑:
这是常见消息的一个例子
(7倍\ xecM \ X00 \ X00 \ X00 \ X00 \ X15。\ X90 \ XF1 \ xc64CIDM')
并且里面有更高级别的信息
('C \ x01dC \ x02H \ x00 \ x15。\ xe8 \ xf3 \ xc64CIEN')
答案 0 :(得分:3)
Construct是一个很好的解析二进制数据的库。
您可以使用以下内容:
from construct import *
message = Struct("wrapper",
UBInt16("length"),
UBInt8("count"),
Byte("id"),
UBInt32("sequence"),
Array(lambda ctx: ctx.length,
Struct("message",
UBInt8("length"),
UBInt8("type"),
Bytes("content", lambda ctx: ctx.length),
),
),
)
答案 1 :(得分:1)
我认为你可以使用Python的bitsrting模块
http://code.google.com/p/python-bitstring/
它为您提供了一些很好的功能,包括二进制数据的格式字符串。
您可以在此处找到有关读取数据和格式化字符串的更多信息
http://pythonhosted.org/bitstring/reading.html#reading-using-format-strings
http://pythonhosted.org/bitstring/constbitstream.html#bitstring.ConstBitStream.read
http://pythonhosted.org/bitstring/constbitstream.html#bitstring.ConstBitStream.readlist
此代码可能会让您了解使用bitstring的解决方案。
from bitstring import BitStream
bs = BitStream(your_binary_data)
length, message_count, id, sequence = bs.readlist('uintle:16, uintle:8, bytes:1, uintle:32')
payload = bs[:bs.pos]
message_length, message_type = payload.readlist('uintle:8, bytes:1')
rest_of_data = payload[:payload.pos]