我用三种不同的格式-gbk\utf-8\ucs-2来编辑三个具有相同内容“你”(英文为you
)的文件,其gedit名为“ok1,ok2,ok3”。
>>> f1 = open('ok1', 'rb').read()
>>> f2 = open('ok2', 'rb').read()
>>> f3 = open('ok3', 'rb').read()
>>> f1
'\xc4\xe3\n'
>>> f2
'\xe4\xbd\xa0\n'
>>> f3
'`O\n\x00'
>>> hex(ord("`"))
'0x60'
>>> hex(ord("O"))
'0x4f'
实际上f3是'\x60\x4f',
但是以下输出使我感到困惑
>>> '\xe4\xbd\xa0'.decode("utf-8")
u'\u4f60'
>>> '\xc4\xe3'.decode("gbk")
u'\u4f60'
>>>
为什么在ucs-2(或说unicode)中仅存在endian问题,而在utf-8中而不是gbk中呢?
最佳答案
UTF-8和GBK以字节顺序存储数据。在这些编码中,强烈定义了哪个字节值位于哪个字节值之后。该字节顺序不会随编码,传输或解码中使用的体系结构而改变。
另一方面,UCS-2或新的UTF-16以2字节的顺序存储数据。这些2字节 token 中各个字节的顺序是字节顺序,它取决于基础计算机体系结构。在与UCS-2编码的数据通信之前,系统必须就如何识别 token 的字节序达成协议(protocol)。
在您的情况下,Unicode点U + 4F60在UCS-2中编码为单个2字节 token 0x4F60
。由于您的机器将最低有效字节放在内存对齐的最高有效字节之前,因此序列('0x60', '0x4F')
已放入文件中。因此,文件读取将按此顺序产生字节。
Python仍然可以正确解码此数据,因为它将在形成2字节 token 之前按正确的顺序读取字节:
>>> '`O\n\x00'.decode('utf-16')
u'\u4f60\n'
关于python - unicode endian使我感到困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12328740/