什么是最好的UTF

时间:2011-07-30 09:33:50

标签: unicode utf-8 utf

我对Unicode中的UTF感到困惑。

有UTF-8,UTF-16和UTF-32。

我的问题是:

  1. 支持所有Unicode块的UTF是什么?

  2. 什么是最好的UTF(性能,尺寸等),为什么?

  3. 这三个UTF之间有什么不同?

  4. 什么是字节顺序和字节顺序标记(BOM)?

  5. 由于

6 个答案:

答案 0 :(得分:28)

  

支持所有Unicode块的UTF是什么?

所有UTF编码都支持所有Unicode块 - 没有UTF编码不能代表任何Unicode代码点。但是,一些非UTF,较旧的编码,例如UCS-2(类似于UTF-16,但缺少代理对,因此缺乏编码高于65535 / U + FFFF的代码点的能力),可能不会。

  

什么是最好的UTF(性能,大小等),为什么?

对于主要是英语和/或仅ASCII的文本数据,UTF-8是迄今为止最节省空间的。但是,UTF-8的空间效率通常低于UTF-16和UTF-32,其中大多数使用的代码点都很高(例如大型CJK文本)。

  

这三个UTF有什么不同?

UTF-8将每个Unicode代码点编码为一到四个字节。 Unicode值0到127与ASCII中的相同,编码方式与ASCII格式相同。值为128到255的字节用于多字节代码点。

UTF-16以两个字节(一个UTF-16值)或四个字节(两个UTF-16值)对每个Unicode代码点进行编码。基本多语言平面中的任何内容(Unicode代码点0到65535,或U + 0000到U + FFFF)都使用一个UTF-16值进行编码。来自较高平原的代码点通过称为“代理对”的技术使用两个UTF-16值。

UTF-32不是Unicode的可变长度编码;所有Unicode代码点值都按原样编码。这意味着U+10FFFF被编码为0x0010FFFF

  

什么是字节顺序和字节顺序标记(BOM)?

字节顺序是一段数据,特定CPU架构或协议如何对多字节数据类型的值进行排序。 Little-endian系统(例如x86-32和x86-64 CPU)将最不重要的字节放在第一位,而big-endian系统(例如ARM,PowerPC和许多网络协议)将最重要的字节放在第一位。

在小端编码或系统中,32位值0x12345678作为0x78 0x56 0x34 0x12存储或传输。在大端编码或系统中,它以0x12 0x34 0x56 0x78存储或传输。

在UTF-16和UTF-32中使用字节顺序标记来表示文本将被解释为哪个字节顺序。 Unicode以巧妙的方式实现这一点 - U + FEFF是一个有效的代码点,用于字节顺序标记,而U + FFFE则不是。因此,如果文件以0xFF 0xFE开头,则可以假定文件的其余部分以小端字节顺序存储。

UTF-8中的字节顺序标记在技术上是可行的,但由于显而易见的原因,在字节顺序的上下文中没有意义。但是,以UTF-8编码的BOM开头的流几乎肯定意味着它是UTF-8,因此可以用于识别。

UTF-8的好处

  • ASCII是UTF-8编码的子集,因此是将ASCII文本引入“Unicode世界”而不必进行数据转换的好方法
  • UTF-8文本是ASCII文本的最紧凑格式
  • 有效的UTF-8可以按字节值排序并生成排序的代码点

UTF-16的好处

  • UTF-16比UTF-8更容易解码,即使它是可变长度编码
  • 对于BMP中的字符,UTF-16比UTF-8更节省空间,但在ASCII之外

UTF-32的好处

  • UTF-32不是可变长度的,因此它不需要特殊的逻辑来解码

答案 1 :(得分:18)

答案 2 :(得分:6)

  1. 所有这些都支持所有Unicode代码点。

  2. 它们具有不同的性能特征 - 例如,UTF-8对于ASCII字符更紧凑,而UTF-32更容易处理整个Unicode,包括基本多语言平面之外的值(即U之上) + FFFF)。由于每个字符的宽度可变,因此UTF-8字符串难以用于获取二进制编码中的特定字符索引 - 您需要进行扫描。除非您知道没有非BMP字符,否则UTF-16也是如此。

  3. 查看UTF-8UTF-16UTF-32

  4. 的维基百科文章可能最简单
  5. Endianness确定(对于UTF-16和UTF-32)最高有效字节是第一个,最低有效字节是最后一个,反之亦然。例如,如果要以UTF-16表示U + 1234,则可以是{0x12,0x34}或{0x34,0x12}。 字节顺序标记表示您正在处理的字节顺序。 UTF-8没有不同的字节序,但在文件开头看到UTF-8 BOM表是 UTF-8的好指标。

答案 3 :(得分:3)

这里有一些很好的问题,已经有了几个很好的答案。我或许可以添加一些有用的东西。

  1. 如前所述,所有三个都覆盖了整套可能的代码点,U + 0000到U + 10FFFF。

  2. 取决于文字,但这里有一些可能感兴趣的细节。 UTF-8每个字符使用1到4个字节; UTF-16使用2或4; UTF-32总是使用4.有用的是要注意这一点。如果您使用UTF-8,那么英文文本将使用每个字节中的绝大多数字符进行编码,但中文每个需要3个字节。使用UTF-16,英语和中文都需要2.所以基本上UTF-8是英语的胜利; UTF-16是中国人的胜利。

  3. 主要区别在上面#2的答案中提到,或者如Jon Skeet所说,请参阅维基百科的文章。

  4. 字节顺序:对于UTF-16和UTF-32,这指的是字节出现的顺序;例如,在UTF-16中,字符U + 1234可以编码为12 34(大端)或34 12(小端)。 BOM或字节顺序标记很有趣。假设您有一个以UTF-16编码的文件,但您不知道它是大端还是小端,但您注意到该文件的前两个字节是FE FF。如果这是big-endian,那么角色将是U + FEFF;如果是小端,它将表示U + FFFE。但事情就是这样:在Unicode中,代码点FFFE是永久未分配的:那里没有字符!因此我们可以告诉编码必须是big-endian。 FEFF角色在这里是无害的;它是ZERO-WIDTH NO BREAK SPACE(基本上是看不见的)。同样,如果文件以FF FE开头,我们知道它是小端。

  5. 不确定我是否在其他答案中添加了任何内容,但我发现英语与中文的具体分析在过去向其他人解释时非常有用。

答案 4 :(得分:2)

观察它的一种方式是尺寸大于复杂性。通常,它们增加了编码文本所需的字节数,但降低了解码用于表示字符的方案的复杂性。因此,UTF-8通常很小,但解码起来很复杂,而UTF-32占用更多字节但很容易解码(但很少使用,UTF-16更常见)。

考虑到这一点,通常选择UTF-8进行网络传输,因为它的尺寸较小。而选择UTF-16时,更容易解码比存储大小更重要。

物料清单用作文件开头的信息,用于描述已使用的编码。但是,这些信息经常丢失。

答案 5 :(得分:2)