0

いくつかのバイト値を比較しようとしています - ソース A は、「読み取られている」ファイルからのものです。

f = open(fname, "rb")
f_data = f.read()
f.close()

これらのファイルは、数 Kb から数 Mb の大きさになる可能性があります。

ソース B は、既知のパターンの辞書です。

eof_markers = {
    'jpg':b'\xff\xd9',
    'pdf':b'\x25\x25\x45\x4f\x46',
    }

(このリストは、基本的なプロセスが機能するようになると拡張されます)

基本的に、私はファイル (ソース A) を「読み取ろう」としており、パターン リストに一致する最後のバイトをインクリメンタルに検査します。testString = f_data[-counter:]一致が見つからない場合は、カウンターを 1 増やし、リストに対してパターン マッチを再度試行します。 .

これを機能させるためにさまざまな方法を試しましたが、testStringを正しくインクリメントすることはできますが、さまざまなアプローチでバイトをASCII化して比較を行うエンコードの問題が発生し続けています。

私は少し迷っており、に変更intするコードをさまよい、予約された値であるなどの過去の問題を取得uしていないため、ASCII 型比較ツールを使用できないなどのことは初めてではありません(結果はbd9if format_type in testString:UnicodeDecodeError: 'ascii' codec can't decode byte a9

私はすべてを整数に変換しようとしましたが、それはこのエラーをスローしていました:ValueError: invalid literal for int() with base 2: '.'または、16 進バイトValueError: invalid literal for int() with base 10: '.'に変換しようとしましたtestStringが、取得し続けましたTypeError: hex() argument can't be converted to hex(これは、私が確信している何よりも私の理解不足です!...)

エンコーディングと 16 進数の比較について説明しているリソースがいくつか見つかりました。完全に理解できるもの、または正しい道を示してくれるものが見つからないだけです。

私はこれに固執していたので、どんな指摘もありがたく受け取っています。

4

2 に答える 2

1

何をしようとしているのか正確にはわかりませんが、このコードは Python 3.2.3 で実行しました。

#f = open(fname, "rb")
#f_data = f.read()
#f.close()
f_data = b'\x12\x43\xff\xd9\x00\x23'
eof_markers = {
    'jpg':b'\xff\xd9',
    'pdf':b'\x25\x25\x45\x4f\x46',
    }

for counter in range(-4, 0):
  for name, marker in eof_markers.items():
    print(counter, ('' if marker in f_data[counter:] else '!') + name)

ハードコーディングされた f_data を使用していますが、1 ~ 3 行目と 4 行目のコメントを解除するだけで元に戻すことができます。

出力は次のとおりです。

-4 !pdf
-4 jpg
-3 !pdf
-3 !jpg
-2 !pdf
-2 !jpg
-1 !pdf
-1 !jpg

あなたがする必要があるのにこれがしていないことはありますか?

于 2012-09-25T00:24:16.027 に答える
0

サブ投稿を作成する代わりに、メイン投稿にコメントする方法がわかりません。とにかく、私はあなたの質問のいくつかに答えています..

  • int(v) は、文字 ("!" など) を整数値に変換するのではなく、書式設定された数値 (たとえば '599') を整数に変換します。そのためには ord() が必要です。ただし、この状況でどちらかを使用する必要がある理由はわかりません。

  • 16 進数 != 2 進数。16 進数は単なる基数です。Binary は、値によっては印刷できない生のバイト値です。これが、"\xfd" のようなエスケープ コードとして表示される理由です。これが、Python が印刷できない文字を 16 進コードとして表す方法です。ただし、それらは特別なステータスのない単一の文字であり、変換する必要はありません。「A」と「\xfd」を比較することは完全に有効です。したがって、まったく変換せずに比較を行うことができるはずです。

  • 'u' を 'b' に変更しても実際に効果があるのは、Python 3.x を実行している場合のみです。

問題を直接的に解決するということに関しては、あなたがやりたいことは明らかですが、なぜそのようなことをすることを選択したのかは明らかではないように感じます。より良い答えを得るには、より明確な質問をする必要があります。

別のアプローチの例を次に示します。

# convert eof markers to a list of characters
eof_markers = {k: list(v) for k,v in eof_markers.items()}

# assuming that the bytes you have read in are being added to a list,
# we can then do a check for the entire EOF string by:

# outer loop reading the next byte, etc, omitted.
for mname, marker in eof_markers.items():
    nmarkerbytes = len(marker) 
    enoughbytes = len(bytes_buffer) >= nmarkerbytes
    if enoughbytes and bytes_buffer[-nmarkerbytes:] == marker:
        location = f.tell()
        print ('%s marker found at %d' % (mname, location))

バイトまたはバイト配列を使用する他の高速なアプローチ (たとえば、'rfind' メソッドを使用) がありますが、これは説明する最も簡単なアプローチです。

于 2012-09-25T00:55:05.247 に答える