python3 编码转换问题😂十进制数组转 unicode

2016-12-13 14:56:15 +08:00
 toono

假设现在有数组 arr = [96, 79, 125, 89]

数组内的每个数的 16 进制数分别为 60, 4f, 7d, 59

而字符串“你好”的 unicode 编码是 '\u4f60\u597d'

问:怎么将十进制数组转换成 unicode 字符?(希望是由内置的函数去转换,手动拼接的话太蓝瘦了)

详情:这是我在通过 pywin32 的 SendMessage 获取文本框内容时遇到的问题,因为因为是用 PyBuffer 来接收返回的内容,所以得到的是一个数组,很纠结怎么转换成字符

4009 次点击
所在节点    Python
8 条回复
raysonx
2016-12-13 15:02:05 +08:00
~> python3
Python 3.5.2 (default, Sep 14 2016, 11:28:32)
[GCC 6.2.1 20160901 (Red Hat 6.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import struct
>>> arr = [96, 79, 125, 89]
>>> struct.pack('B' * len(arr), *arr).decode('utf-16')
'你好'
>>>
raysonx
2016-12-13 15:02:54 +08:00
或者直接
>>> bytes(arr).decode('utf-16')
'你好'
raysonx
2016-12-13 15:06:51 +08:00
需要澄清的一個問題是,「字符串“你好”的 unicode 编码是 '\u4f60\u597d'」表述有誤。
Unicode 是字符集,它只負責對每一個符號賦於一個編號,並不關心這個符號的二進制表示行式。
而樓主的需求是,對一串 bytes 按 UTF-16 進行解碼( decode )。
Unicode 是字符集(charset), UTF 是編碼(encoding),不要搞混了。
toono
2016-12-13 15:14:16 +08:00
@raysonx 嗯嗯,谢谢耐心科普!!!!
imn1
2016-12-13 15:15:18 +08:00
如楼上所述, unicode 是个字符集,是个“类映射表”概念, ucs2, utf-7/8/16/32 等等才能称为编码

一般处理字符串的话, 2L 所写 bytes 比较方便,但主楼所写场景,如果考虑有可能其他混合数据, 1L 所写 struct 可能更适合
raysonx
2016-12-13 15:23:00 +08:00
哦對了, UTF-16 有一個討厭的問題,就是分大小端序( endianness )。
題主的例子是小端序(little endian , UTF-16LE)的,即每一個字符低位 byte 在前,高位 byte 在後(「你好」對應 60, 4f, 7d, 59 )。
還有一種是大端序(big endian , UTF-16BE),即每一個字符高位 byte 在前,低位 byte 在後(「你好」對應 4f, 60, 59, 7d )。

同樣的, UTF-32 也分大小端序。不過 UTF-8 不分大小端序。
toono
2016-12-13 15:38:01 +08:00
@imn1 嗯嗯, 1L 和 2L 的方法都方便,我暂时还没有数据混合,所以 2L 的够用了。你们这些概念好透彻啊,我是刚从事 python 开发,太小白了。
toono
2016-12-13 15:39:49 +08:00
@raysonx 对,我也发现了,所以如果实在没有办法了,就先将两个整数换顺序,然后转到 16 进制,再拼接成 unicode 字符的表示形式😛

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/327324

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX