4

我从未在 python 中处理过具有多种数据类型的二进制文件。我希望我能找到一些方向。二进制文件包含以下数据类型:

String
Byte
UInt8 -以字节为单位的大小:1- 8 位无符号整数。
UInt16 -以字节为单位的大小:2- Little-endian 编码的 16 位无符号整数。
UInt32 - 字节大小:4- Little-endian 编码的 32 位无符号整数。
UInt64 -以字节为单位的大小: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。

编辑:这是常见消息
('7x\xecM\x00\x00\x00\x00\x15.\x90\xf1\xc64CIDM')
和其中的更高级别消息
('C\x01dC\x02H\x00 \x15.\xe8\xf3\xc64CIEN')

4

2 回答 2

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),
        ),
    ),
)
于 2013-09-28T09:45:09.020 回答
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

此代码可能会让您了解使用位串的解决方案。

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]
于 2013-09-25T10:27:30.723 回答