0

バイナリ ファイル (jpg、mp3 など) を Web セーフ テキストに変換してから、バイナリ データに戻したいと考えています。いくつかのモジュールを調査しましたが、非常に近いと思いますが、データが破損し続けています。

binasciiのドキュメントを見た後、私はこれを思いつきました:

from binascii import *
raw_bytes = open('test.jpg','rb').read()
text = b2a_qp(raw_bytes,quotetabs=True,header=False)
bytesback = a2b_qp(text,header=False)
f = open('converted.jpg','wb')
f.write(bytesback)
f.close()

を開こうとするとconverted.jpg、データが破損します:-/

b2a_base64また、バイナリ データの 57 ブロックの長さで使用してみました。各ブロックを取得して文字列に変換し、それらをすべて連結してから、元に戻すa2b_base64と再び破損しました。

誰でも助けることができますか?私は、バイトとファイル形式のすべての複雑さに精通しているわけではありません。\r\nそれが違いを生む場合、私はWindowsでPythonを使用しています

4

4 に答える 4

1

ドキュメント リファレンスは Python 3.0.1 用です。Python 3.0 を使用する正当な理由はありません。3.2 または 2.7 を使用する必要があります。正確には何を使用していますか?

提案: (1)組み込みとの混乱を避けるために変更bytesします (2)テスト スクリプトで==をチェックします (3) テストは quoted-printable で動作するはずですが、バイナリ データには非常に非効率的です。代わりに base64 を使用してください。raw_bytesbytesraw_bytesbytes_back

更新: Base64 エンコーディングでは、3 入力バイトごとに 4 出力バイトが生成されます。56 は 3 の整数倍ではないため、base64 コードは 56 バイトのチャンクでは機能しません。各チャンクは 3 の倍数にパディングされます。次に、チャンクを結合してデコードを試みますが、動作しないことが保証されています。

あなたのチャンキングループは、次のように書く方がはるかに良いでしょう:

output_string = ''.join(
    b2a_base64(raw_bytes[i:i+57]) for i in xrange(0, xrange(len(raw_bytes), 57)
    )

いずれにせよ、チャンキングはかなり遅く、無意味です。ただするb2a_base64(raw_bytes)

于 2011-10-23T20:08:49.800 に答える
1

quoted printable の代わりに base64 エンコーディングを使用する必要があります。とを使用b2a_base64()a2b_base64()ます。

Quoted printable は、写真などのバイナリ データの場合、はるかに大きくなります。このエンコーディングでは、各バイナリ (非英数字) コードが に変更され=HEXます。メールの件名など、主に英数字で構成されるテキストに使用できます。

Base64 は、主にバイナリ データに適しています。最初のバイトの 6 バイト、次に 1 バイト目の最後の 2 ビット、2 バイト目の 4 バイトが必要です。=エンコードされたテキストの末尾にパディングすることで認識できます (他の文字が使用される場合もあります)。

例として、271 700 バイトの .jpeg を取り上げました。qp では 627 857 b ですが、base64 では 362 269 バイトです。qp のサイズはデータ型に依存します。文字のみのテキストは変更されません。base64のサイズは ですorig_size * 8 / 6

于 2011-10-23T19:48:17.797 に答える
-2

質問からコピーされた@PMCの回答:

機能するものは次のとおりです。

from binascii import *
raw_bytes = open('28.jpg','rb').read()
str_list = []
i = 0
while i < len(raw_bytes):
    byteSegment = raw_bytes[i:i+57]
    str_list.append(b2a_base64(byteSegment))
    i += 57
bytesBackAll = a2b_base64(''.join(str_list))
print bytesBackAll == raw_bytes #True

助けてくれてありがとう。なぜこれが [0:57] ではなく [0:56] で失敗するのかはわかりませんが、それは読者の演習として残しておきます :P

于 2011-10-24T05:44:31.447 に答える