UTF-16有什么意义?

时间:2011-03-13 20:28:00

标签: utf-8 character-encoding utf-16 utf utf-32

我从未理解UTF-16编码的观点。如果您需要能够将字符串视为随机访问(即代码点与代码单元相同),则需要UTF-32,因为UTF-16仍然是可变长度的。如果你不需要这个,那么与UTF-8相比,UTF-16似乎是一种巨大的空间浪费。 UTF-16优于UTF-8和UTF-32有什么优势?为什么Windows和Java将它用作本机编码?

5 个答案:

答案 0 :(得分:45)

当Windows NT设计时,UTF-16不存在(NT 3.51诞生于1993年,而UTF-16诞生于1996年,采用Unicode 2.0标准);而是UCS-2,当时足以保存Unicode中的每个字符,因此1代码点= 1代码单位等价实际上是真的 - 字符串不需要可变长度逻辑。

他们稍后转向UTF-16,以支持整个Unicode字符集;但是它们无法移动到UTF-8或UTF-32,因为这会破坏API接口中的二进制兼容性(除此之外)。

对于Java,我不太确定;自从1995年发布以来,我怀疑UTF-16已经播出(即使它尚未标准化),但我认为与基于NT的操作系统的兼容性可能在他们的选择中发挥了一定作用(连续)每次调用Windows API的UTF-8< - > UTF-16转换都会引起一些减速。)


修改

维基百科解释说,即使对于Java,它也是以同样的方式:它最初支持UCS-2,但在J2SE 5.0中转移到UTF-16。

所以,通常当你看到在某些API / Framework中使用的UTF-16时,它是因为它以UCS-2开头(为了避免字符串管理算法中的复杂性),但它转移到UTF-16以支持代码在BMP之外的点,仍然保持相同的代码单元大小。

答案 1 :(得分:17)

除了向后兼容性回复之外,没有任何回复表明UTF-16优于UTF-8有任何意义。

嗯,我的评论有两点需要注意。

Erik表示:“UTF-16覆盖了整个BMP的单个单元 - 因此,除非您需要BMP之外的稀有字符,否则UTF-16实际上是每个字符2个字节。”

警告1)

如果您可以确定您的应用程序永远不需要BMP之外的任何字符,并且您编写的任何用于它的库代码将永远不会用于任何需要BMP之外的字符的应用程序,那么你可以使用UTF-16,并编写代码,隐含假设每个字符的长度恰好是两个字节。

这看起来非常危险(实际上,很愚蠢)。

如果您的代码假定所有UTF-16字符的长度都是两个字节,并且您的程序与BMP之外存在单个字符的应用程序或库进行交互,那么您的代码将会中断。必须编写检查或操作UTF-16的代码来处理需要超过2个字节的UTF-16字符的情况;因此,我“解雇”这个警告。

UTF-16编码并不比UTF-8简单(两者的代码都必须处理可变长度的字符)。

警告2)

UTF-16如果写得恰当,可能会在计算上更有效率。

像这样:假设某些长字符串很少被修改,但经常被检查(或者更好,永远不会修改一次构建 - 即,字符串构建器创建不可修改的字符串)。可以为每个字符串设置一个标志,指示该字符串是否仅包含“固定长度”字符(即,不包含长度不完全是两个字节的字符)。标志为true的字符串可以使用优化代码进行检查,该代码假定为固定长度(2字节)字符。

空间效率怎么样?

对于A)字符来说,UTF-16显然更有效率,UTF-16需要的字节数要少于UTF-8。

对于B)字符来说,UTF-8显然更有效率,UTF-8需要的字节数比UTF-16要少。

除了非常“专业”的文本外,计数(B)可能远远超过计数(A)。

答案 2 :(得分:3)

UTF-16覆盖整个BMP单个单元 - 因此,除非您需要BMP之外的稀有字符,否则UTF-16实际上是每个字符2个字节。 UTF-32占用更多空间,UTF-8需要可变长度支持。

答案 3 :(得分:1)

UTF16通常用作直接映射到多字节字符集,即onyl原始的0-0xFFFF分配字符。

这为您提供了两个世界中最好的,你有固定的字符大小,但仍然可以打印任何人可能使用的所有字符(正统的克林顿宗教脚本除外)

答案 4 :(得分:1)

UTF-16允许将所有基本多语言平面(BMP)表示为单个代码单元。超出U + FFFF的Unicode代码点由代理对表示。

有趣的是Java和Windows(以及其他使用UTF-16的系统)都在代码单元级别运行,而不是Unicode代码点级别。因此,由单个字符U + 1D122(MUSICAL SYMBOL F CLEF)组成的字符串在Java中编码为“\ ud824 \ udd22”和"\ud824\udd22".length() == 2(不是1)。所以这是一种黑客攻击,但事实证明,角色不是可变长度。

UTF-16优于UTF-8的优势在于,如果与UTF-8一起使用相同的黑客,则会放弃太多。