4

Pythonで複数のデータ型を持つバイナリファイルを扱ったことはありません。何か方向性が見えてきたらいいなと思っていました。バイナリ ファイルには、次のデータ型が含まれています。

String
Byte
UInt8 -バイト単位のサイズ: 1 - 8 ビットの符号なし整数。
UInt16 -バイト単位のサイズ: 2 - リトル エンディアンでエンコードされた 16 ビットの符号なし整数。
UInt32 -バイト単位のサイズ: 4 - リトル エンディアンでエンコードされた 32 ビット符号なし整数。
UInt64 -バイト単位のサイズ: 8 - リトル エンディアンでエンコードされた 64 ビット符号なし整数。

私がうまくいかなかったのは、データを適切にデコードすることです。データには、1 つ以上のより高いレベルのメッセージを配信するためのラッパーとして機能する共通のメッセージ形式が含まれています。このラッパーに含まれるフィールド名の下に提供しました。

このメッセージ内に次のものを含めることができます:
長さ- オフセット 0 - サイズ 2 - タイプ UInt16
メッセージ カウント - オフセット 2 - サイズ 1 - タイプ UInt8
ID - オフセット 3 - サイズ 1 - タイプ バイト
シーケンス - オフセット 4 - サイズ 4 - タイプ UInt32
ペイロード-オフセット 8

長さが共通メッセージの長さを指定する場合、メッセージ カウントは、ペイロード内で開始されるより高いレベルのメッセージの数を示します。

上位レベルのメッセージは、次の特性を持つペイロードで始まります

メッセージの長さ - 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 http://code.google.com/p/python-bitstring/の bitrting モジュールを使用できると思います。
これは、バイナリ データの書式文字列を含むいくつかの優れた機能を提供します。

ここでは、データの読み取りとフォーマット文字列について詳しく説明します。
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 に答える