2

过去我用 Python 3.2 搞砸了,但现在我面临一个关于 Python 中 utf-8 编码的有点混乱的情况。
例如,假设我有这段代码:

'א'.encode()

结果是b'\xd7\x90'(或0xD790),然而,这是错误的:希伯来字符 Alef 的 utf-8 编码应该是0x5D0
但是,使用 utf-16 作为编码会返回正确的十六进制值,前缀为0xFFFE

'א'.encode('utf-16')

这返回b'\xff\xfe\xd0\x05'

我觉得我的理解中缺少一些基本的东西,所以
用户,请帮助教育我!

4

3 回答 3

8

א的unicode代码点是 U+05D0二进制101 1101 0000。11 位代码点 ABCDEFGHIJK 的 UTF-8 编码

110A BCDE  10FG HIJK
# i.e.
1101 0111  1001 0000 # binary
 d    7     9    0   # hex

或者,在 Python 表示法中,b'\xd7\x90'.

于 2012-05-28T19:39:35.947 回答
6

0x5d0根本不是编码;它只是一个数字。是的,希伯来字母 ALEF 是 U+05D0,但 UTF-8 不是将代码点转录为字节。相反,它在每个字节的 MSb 中使用一组固定的位,并使用来自代码点值的可变位数填充 LSb。

0x5d0 = 101 1101 0000
      = 10111 010000

插入110xxxxxx 10xxxxxx我们得到:

11010111 10010000 = 0xd7 0x90
于 2012-05-28T19:38:23.590 回答
4

不,unicode 代码点א0x5d0:

print("%x" % ord('א'))  
# '5d0'

当您对其进行编码时,utf-8您将获得一种表示该特定代码点的可能方式。utf-16将是另一种表示它的方式,它使用 2 个字节表示每个代码点。你得到它前缀的原因\xff\xfe是它会encode('utf-16')生成一个字节顺序标记(BOM)。如果您明确指定字节顺序,则不会生成它:

>>> a='א'
>>> a.encode('utf-16')
b'\xff\xfe\xd0\x05'
>>> a.encode('utf-16-le')
b'\xd0\x05'
>>> a.encode('utf-16-be')
b'\x05\xd0'
于 2012-05-28T19:44:45.857 回答