如何读取具有给定结构的多种数据类型的二进制文件

时间:2013-09-25 09:15:37

标签: python types binary binaryfiles

我从来没有在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')

2 个答案:

答案 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]