2016-08-02 18 views
1

私はutf-8でエンコードされた文字列を表すバイトの配列を持っています。これらのバイトをPyton2の文字列にデコードしたい。私は私の全体的なプログラムのためにPython2に依存しているので、Python3に切り替えることはできません。Python2でutf-8バイト配列を文字列にデコードするにはどうしたらいいですか?

array = [67, 97, 102, **-61, -87**, 32, 70, 108, 111, 114, 97] 

- >カフェéフローラ

私がしたい文字列内のすべての文字は、必ずしも配列に正確に1バイトで表現されていないので、私のようなソリューションを使用することはできません。

"".join(map(chr, array)) 

0〜127(ASCII)の範囲にない数値が出現するたびに、新しい16ビット整数を作成し、現在のビットを8より左側にシフトして、次のbを追加しますビット単位のORを使用してください。最後に、unichr()を使ってデコードします。

result = [] 


for i in range(len(byte_array)): 
    x = byte_array[i] 
    if x < 0: 
     b16 = x & 0xFFFF # 16 bit 
     b16 = b16 << 8 
     b16 = b16 | byte_array[i+1] 
     result.append(unichr(m16)) 
    else: 
     result.append(chr(x)) 

return "".join(result) 

しかし、これは失敗でした。

次の記事は非常によく問題を説明し、nodeJSソリューションが含まれています。UTF-8でそれを

http://ixti.net/development/node.js/2011/10/26/get-utf-8-string-from-array-of-bytes-in-node-js.html

+3

ためstruct.packを使用することができます。 – user2357112

+0

0から128までのすべての数字を「00」で「パッド」することはできませんか? –

+0

あなたがinmy答えを見ることができるように、mapとchrのバージョンでの結合はほとんどうまくいきますが、あなたは負の数を持っています。私の答えは、より読みやすいジェネレータ表現を使用し、負の数を処理することで、同じことが不可欠です。 – jsbueno

答えて

1

あなたはUTF-8のデコードがどのように動作するかではないことを、この

>>> a = [67, 97, 102, -61, -87, 32, 70, 108, 111, 114, 97] 
>>> struct.pack("b"*len(a),*a) 
'Caf\xc3\xa9 Flora' 
>>> print struct.pack("b"*len(a),*a).decode('utf8') 
Café Flora 
2

バイト文字列へのご入力を変換するために少し-使用array moduleを使用して、decodeコーデック:

import array 
decoded = array.array('b', your_input).tostring().decode('utf-8') 
+0

'ValueError:バイトは範囲(0,256)にある必要があります ' – wim

+0

これは私にValueErrorを与えます:バイトは範囲(0,256)にある必要があります –

+0

@wim:ああ、ハァッ。彼らは、符号なしではなく入力で値を署名しています。これは直接動作しません。 – user2357112

1

あなたは心の中で持っている必要がありPython2で「文字列」は文字にマップするために起こる適切なテキスト、メモリ内のバイトだけシーケンスでないときに「印刷」それらの文字列 - バイトシーケンス内の目的の文字のマッピングが端末のものと一致する場合、適切に書式設定されたテキストが表示されます。

端末がUTF-8でない場合、メモリに適切なバイト文字列があっても、印刷するだけで間違った結果が表示されます。そのため、式の最後に余分な「デコード」ステップが必要です。

text = b''.join(chr(i if i > 0 else 256 + i) for i in array).decode('utf-8') 

ソースが負の数として128と255の間の数字をエンコードとして、オペレータが「CHR」を呼び出す前に、値を再正規化するために、「場合」は、我々はインラインを持っています。

「あなたが望む文字列のすべての文字が必ずしも配列内の正確に1バイトで表現されるわけではないので、あなたは言う - あなたがPython2.x文字列を使用する場合、それをどう扱うのですか?とにかく端末適切なtetを扱う場合は、数字を適切な(バイト)文字列に結合した後で、 "decode"メソッドを使用します - これはUTF-8マルチバイトのエンコードされた文字について知り、 (文字列)文字列オブジェクト(Python 2の 'unicode'オブジェクト) - 各文字をエンティティとして扱います。

+0

'i> iが0> else i + 0xFF'と書くことができます。 –

+0

セマンティクな理由からはうまくいくかもしれませんが、私はそれをお勧めしません。それは数字を正にするために "&"操作の副作用を悪用します。おそらく、 "最も正しい"方法はstructを使った@ Joranの答えですが、それを実行するのには不確実です。このようにして、「弦で考える」方法です。 :-) – jsbueno

関連する問題