2017-08-09 118 views
2

我在python中试过这个以字节为单位的字符串长度。python3.5中使用不同编码的字符串的长度

>>> s = 'a' 
>>> s.encode('utf-8') 
b'a' 
>>> s.encode('utf-16') 
b'\xff\xfea\x00' 
>>> s.encode('utf-32') 
b'\xff\xfe\x00\x00a\x00\x00\x00' 
>>> len(s.encode('utf-8')) 
1 
>>> len(s.encode('utf-16')) 
4 
>>> len(s.encode('utf-32')) 
8 

UTF-8使用存储英语字符一个字节,但是为什么UTF-16使用4个字节? len()是什么措施?

回答

2

UTF-16是一种可变长度编码;码点用一个或两个16位代码单元(即2或4个字节,'a'为2个字节)编码。

UTF-32是固定宽度,每个代码点恰好为32位(即4个字节)。

你看到的长度看起来似乎膨胀了,因为当你像那样天真地使用len时(包括\ xff \ xfe thing是BOM),你会看到BOM

>>> 'a'.encode('utf-16') 
b'\xff\xfea\x00' 
    BOM.....a.... 
>>> 'aaa'.encode('utf-16') 
b'\xff\xfea\x00a\x00a\x00' 
    BOM.....a....a....a.... 

如果你看一下使用bitstring模块的原始比特它可能对你更清楚:

>>> # pip install bitstring 
>>> from bitstring import Bits 
>>> Bits(bytes='a'.encode('utf-32')).bin 
'1111111111111110000000000000000001100001000000000000000000000000' 
>>> Bits(bytes='aaa'.encode('utf-32')).bin 
'11111111111111100000000000000000011000010000000000000000000000000110000100000000000000000000000001100001000000000000000000000000' 
BOM.............................a...............................a...............................a............................... 

UTF-8又是宽度可变,用8月1日至4日位块,匹配前128个字符的ASCII,其中包括'a'。 unicode标准允许使用UTF-8的BOM,但既不要求也不建议使用(它在那里没有意义),这就是为什么你在第一个例子中没有看到任何BOM。

0

你的长度看起来很奇怪的原因是UTF-16和UTF-32编码在编码过程中在你的字符串的开头附加了一个byte order mark。这就是为什么琴弦的长度似乎是你所期望的两倍。他们使用两个代码点。字节顺序标记告诉你一些东西(字节顺序和编码是主要的)。所以基本上len的功能就像你期望的那样(它测量编码表示中使用的字节数)。

0

len()返回对象的长度(项目数)。当你编码一个字符串s.encode('utf-16') python返回字符串编码版本字节顺序标记。这是计算在字符串的长度。为了说明我的观点

for i in range(0, len(s.encode('utf-16'))): 
    print(s.encode('utf-16')[:i]) 

结果:

b'' #this is the byte order mark 
b'\xff' 
b'\xff\xfe' 
b'\xff\xfea' 
相关问题