web-dev-qa-db-ja.com

Python

私は次のようにバイナリファイルを開いています:

file = open("test/test.x", 'rb')

リストへの行を読みます。各行は次のようになります。

'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'

このデータを操作するのに苦労しています。各行を印刷しようとすると、pythonがフリーズし、ビープ音が鳴ります(どこかにバイナリビープコードがあると思います)。このデータを安全に使用するにはどうすればよいですか?各16進数を10進数に変換しますか?

16

印刷するには、次のようにします。

print repr(data)

全体として16進数:

print data.encode('hex')

各バイトの10進値の場合:

print ' '.join([str(ord(a)) for a in data])

2進整数などを元々Cスタイルの構造体からのものであるかのようにデータから解凍するには、 struct モジュールを調べます。

25
ʇsәɹoɈ

_\xhh_は16進値hh の文字です。 _._や `〜 'などの他の文字は通常の文字です。

文字列を反復処理すると、文字列内の文字が1つずつ表示されます。

ord(c)は文字を表す整数を返します。 例:ord('A') == 65

これにより、各文字の10進数が出力されます。

_s = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
print ' '.join(str(ord(c)) for c in s)
_
4
Jon-Eric

バイナリデータが「\ n」で区切られた「行」に分割されることはめったにありません。そうである場合は、行末記号としての「\ n」とデータの一部としての「\ n」を区別するための暗黙的または明示的なエスケープメカニズムがあります。エスケープメカニズムの知識がなくても、行などのファイルを盲目的に読み取ることは無意味です。

あなたの特定の懸念に答えるために:

'\ x07'はASCII BEL文字で、元々はテレタイプマシンでベルを鳴らすためのものでした。

ord(b)を実行すると、バイト 'b'の整数値を取得できます。

ただし、バイナリデータを適切に処理するには、レイアウトが何であるかを知る必要があります。符号付きおよび符号なしの整数(サイズ1、2、4、8バイト)、浮動小数点数、さまざまな長さの10進数、固定長文字列、可変長文字列などを使用できます。追加の複雑さは、データが記録されるかどうかに起因します。 bigendianファッションまたはlittleendianファッションで。上記のすべてを知ったら(または十分な情報に基づいて推測できれば)、 Python struct module をすべてまたはほとんどの処理に使用できるはずです。 ctypes module も役立つ場合があります。

データ形式に名前はありますか?もしそうなら、教えてください。コードやドキュメントを紹介できる場合があります。

「このデータを安全に使用するにはどうすればよいですか?」と質問されます。どちらが疑問を投げかけます:あなたはそれを何のために使いたいですか?どんな操作をしたいですか?

2
John Machin

前述のアトラスのように、ordとhexが役立つかもしれません。ファイル内のある種の構造化バイナリデータを解釈しようとする場合は、 struct モジュールが役立つ場合があります。

2
Mattias Nilsson

ASCII文字に変換されたデータを印刷しようとしていますが、機能しません。

データの任意のバイトを安全に使用できます。 16進数で出力する場合は、関数ordおよびhex /を確認してください。

1
Yann Ramin

read()またはreadline()を使用していますか? nバイトを読み取るにはread(n)を使用する必要があります。 readline()は、バイナリファイルにはない改行に到達するまで読み取ります。

ただし、どちらの場合でも、バイト文字列が返されます。これは、印刷可能または印刷不可能な文字である可能性があり、おそらくあまり役​​に立ちません。

必要なのはord()で、これは1バイトの文字列を対応する整数値に変換します。ファイルから一度に1バイトずつread()を実行し、結果に対してord()を呼び出すか、文字列全体を反復処理します。

1
Paul Richter

NumPyと bitstream を使用する場合は、次のことができます。

>>> from numpy import *
>>> from bitstream import BitStream
>>> raw = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
>>> stream = BitStream(raw)
>>> stream.read(raw, uint8, len(stream) // 8)
array([190,   0, 200, 100, 248, 100,   8, 228,  46,   7, 126,   3, 158,
         7, 190,   3, 222,   7, 254,  10], dtype=uint8)