我有一个表示utf-8编码字符串的字节数组。我想将这些字节解码回Pyton2中的字符串。我依靠Python2来完成整个程序,所以我无法切换到Python3。
array = [67, 97, 102, **-61, -87**, 32, 70, 108, 111, 114, 97]
- > Caf é Flora
由于我想要的字符串中的每个字符不一定由数组中的1个字节表示,我不能使用如下解决方案:
"".join(map(chr, array))
我尝试创建一个可以逐步执行数组的函数,每当遇到不在0-127(ASCII)范围内的数字时,创建一个新的16位int,将当前位移到8以上,然后使用按位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解决方案:
http://ixti.net/development/node.js/2011/10/26/get-utf-8-string-from-array-of-bytes-in-node-js.html
答案 0 :(得分:2)
使用很少使用的array
module将您的输入转换为字节字符串,然后使用UTF-8编解码器将其decode
转换为:
import array
decoded = array.array('b', your_input).tostring().decode('utf-8')
答案 1 :(得分: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”之前使用内联“if”运算符重新规范化该值。
只是要清楚 - 你说“因为我想要的字符串中的每个字符都不一定由数组中的1个字节表示,” - 所以 - 如果你使用Python2.x字符串,需要注意的是, 终端无论如何。如果你想处理正确的tet,在将你的数字加到一个合适的(字节)字符串之后,就是使用“decode”方法 - 这是知道UTF-8多字节编码字符的部分并且还给你回来一个(文本)字符串对象(Python 2中的'unicode'对象) - 将每个字符视为一个实体。
答案 2 :(得分:1)
您可以将struct.pack
用于此
>>> 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