0

約 60 kb のファイルがあり、データのみを抽出しようとしています。ファイルには多くの「FF FF FF FF」が含まれており、すべてを抽出しようとしていますが、ここの「FF FF FF FF」は例です。

46 0D 89 2E 16 FC 1E E6 10 C1 6D 4E 1B 74 5F 1F 
81 07 E2 E7 17 14 77 D4 EA AC BC 20 EA 98 27 FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

そして、これを取得するために使用するコードは次のとおりです。

infile = open("file.bin", "rb") 
    new_pos = int("0xFC0000", 16)
    infile.seek(new_pos, 0)
    chunk = int("0x40000", 16)
    data = infile.read(chunk)
    with open("processed_file.bin", "wb") as outfile:
        outfile.write(data)

ファイルを読み取り、「処理済み file.bin」として保存しますが、これらすべての「FF FF」が含まれています。FFのインスタンスがあり、処理済みのfile.binとして保存する前に、「FF FF FF FF」を見つけてファイルから削除する必要があります

任意の入力をいただければ幸いです。

編集:私が何を意味するかをさらに説明するために、この16進数には最後にFFがあります。

81 07 E2 E7 17 14 77 D4 EA AC BC 20 EA 98 27 FF

その FF を最後に保持する必要がありますが、FF FF または FF FF FF FF のインスタンスを削除します。

4

1 に答える 1

0

まず、FF FF明らかに every を削除すると、 every の削除が処理されるFF FF FF FFため、その部分について心配する必要はありません。

アライメントされた s のみを削除したい場合はFF FF、明らかにそれを 2 バイトのチャンクにグループ化します。たとえばgrouper、標準ライブラリのitertools レシピを使用すると、次のようになります。

data = infile.read(chunk)
data_words = grouper(2, data)
data_words_minus_ffff = (word for word in data_words if word != ('\xFF', '\xFF'))
out_data = flatten(data_words_minus_ffff)
with open("processed_file.bin", "wb") as outfile:
    outfile.write(''.join(out_data))

明らかに、これをもっとコンパクトに書くことができます。わかりやすくするために、このようにしました (そのため、list(…)わかりにくい場合に備えて、各ステップを印刷して理解しやすくすることができます)。

しかし、アライメントを気にせずFF、1 よりも長い限り、 の奇数の実行を削除したい場合はどうなるでしょうか? さて、それを実行にグループ化し、1 より長い実行を破棄します。これは次の方法でitertoolsも実行できます。

data = infile.read(chunk)
groups = itertools.groupby(data, key=lambda x: x != '\xff')
groups_listified = ((key, list(group)) for key, group in groups)
groups_without_ff_runs = (group for key, group in groups_listified if key or len(group) > 1)
out_data = flatten(groups_without_ff_runs)
with open("processed_file.bin", "wb") as outfile:
    outfile.write(''.join(out_data))

これは説明するのが少し難しいですが、繰り返しますが、一連の個別のステップとして書いているので、print list(…)各ステップの後にそれが何をしているかを見ることができます.

ビットは、if key or len(group) > 1それが非 FF バイトの連続であるか、1 バイトを超える連続であることを示しています。したがって、これを変更して 2 バイトの FF 実行のみを保持し、長いものは保持しないようにするには、 を に変更len(group) > 1len(group) == 2ます。偶数の長さのランを維持したい場合は、 を使用しますlen(group) % 2 == 0。等々。説明できる条件であれば、そこに置くことができます。

または、多様性のために、明示的に行いましょう。

data = infile.read(chunk)
run = 0
out_data = []
for byte in data:
    if byte == '\xFF':
        run += 1
    else:
        if run != 1:
            out_data.append('\xFF' * run)
        run = 0
        out_data.append(byte)
with open("processed_file.bin", "wb") as outfile:
    outfile.write(''.join(out_data))

繰り返しますがFF、1 バイトより長いすべての実行を保持しています。run != 1代わりに、正確に 2 バイトのすべてのランを保持したい場合は、単にrun == 2. 等々。

于 2013-01-29T01:43:09.850 に答える