1

私は、バイナリ ファイルを開き、頻繁に変化するバイナリ BLOB を見つけ、その BLOB だけを新しいファイルにコピーするための小さなスクリプトをプログラミングしています。

バイナリ ファイルのレイアウトは次のとおりです。

-JUNK (Unknown Size) (Unknown Contents)
-3-byte HEADER containing encoded size of blob
-PADDING (Unknown Size) (Every byte is FF in hex)
-Start of blob (72 bytes) (Unknown Contents)
-16 bytes that are ALWAYS the same
-End of blob (Size can be determined from subtracting (72+16) from value HEADER) (Unknown Contents)
-JUNK (Unknown Size) (Unknown Contents)

これまでに書いたコードは次のとおりです。

from sys import argv
import binascii
import base64

InputFileName = argv[1]

with open(InputFileName, 'rb') as InputFile:

    Constant16 = base64.b64decode("GIhTSuBask6y60iLI2VwIg==")
    Constant16Offset = InputFile.read().find(Constant16)

    InputFile.seek(Constant16Offset)
    InputFile.seek(-72,1)

    InputFile.seek(-1,1)
    FFTestVar = InputFile.read(1)

    while FFTestVar == b'\xFF':
        InputFile.seek(-2,1)
        FFTestVar = InputFile.read(1)

    InputFile.seek(-3,1)
    BlobSizeBin = InputFile.read(3)
    BlobSizeHex = binascii.b2a_hex(BlobSizeBin)
    BlobSizeDec = int(BlobSizeHex, 16)

    InputFile.seek(Constant16Offset)
    InputFile.seek(-72,1)

    Blob = InputFile.read(BlobSizeDec)

    with open('output.bin', 'wb') as OutputFile:

        OutputFile.write(Blob)

残念ながら、whileループは遅いです。InputFile は最大 24MB の大きさになる可能性があり、パディングはその巨大なチャンクになる可能性があります。一度に 1 バイトずつ処理するのはとてつもなく遅いです。

おそらくこれを行うためのより良い方法があると思いますが、1、2 時間のグーグル検索は役に立ちませんでした。

ありがとう!

4

1 に答える 1

2

ファイル全体をメモリに読み込むことができます(実際に行います):

data = InputFile.read()

そして、dataカジュアルな文字列のように扱うことができます(ただし、これは Unicode 文字列ではなく、残念ながらstrPython 2.X で呼び出されるバイトの配列です)。offset属性を作成するため、オフセットを覚えておく必要があります。のように見えるすべての行は、 およびにInputFile.seek(xx)変換する必要があります。offset = xxInputFile.seek(xx, 1)offset += xx

magic_number = base64.b64decode("GIhTSuBask6y60iLI2VwIg==")
offset = magic_number_offset = data.find(magic_number)
offset -= 72

次に、while ループの代わりにモジュールを使用しreます (そのモジュールをインポートする必要があります)。

pattern = re.compile("[^\xFF]\xFF*$")
offset = pattern.search(data, endpos=offset).start() + 1

残りのコードは次のとおりです。

offset -= 3
blob_size_bin = data[offset:offset+3]
blob_size_hex = binascii.b2a_hex(blob_size_bin)
blob_size_dec = int(blob_size_hex, 16)
offset = magic_number_offset - 72
blob = data[offset:offset+blob_size_dec]

ファイルが非常に大きく、Python プロセスが大量のメモリを消費する場合は、ファイルmmap全体をメモリにロードする代わりに module を使用できます。

この解決策がまだ遅い場合は、データの順序を逆にして ( reversed_data = data[::-1])、 pattern を検索できます[^\ff]

于 2012-11-26T09:31:55.647 に答える