UTF-8,UTF-16和UTF-32 Unicode编码在可以存储的字符数量上有所不同?

好的。 我知道这看起来像典型的“为什么他不只是谷歌它或去www.unicode.org并查找? 问题,但是对于这样一个简单的问题,在检查两个来源之后,答案仍然没有解决。

我非常肯定,所有这三种编码系统都支持所有的Unicode字符,但在演示文稿中声明之前我需要确认它。

奖金问题:这些编码是否可以扩展支持的字符数量不同?

不,他们只是不同的编码方法。 他们都支持编码相同的字符集。

UTF-8使用每个字符一到四个字节,取决于你正在编码的字符。 ASCII范围内的字符只需要一个字节,而非常见的字符需要四个字符。

UTF-32每个字符使用四个字节,而不pipe它是什么字符,所以它总是比UTF-8使用更多的空间来编码相同的string。 唯一的优点是可以通过只计算字节来计算UTF-32string中的字符数。

对于大多数字符,UTF-16使用两个字节,对于不寻常的使用四个字节。

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

没有Unicode字符可以存储在一个编码,但不是另一个。 这仅仅是因为有效的Unicode字符已经被限制在可以以UTF-16(其具有三种编码的最小容量)存储的内容。 换句话说,UTF-8和UTF-16 可以用来表示比UTF-16更广泛的字符,但是它们不是 。 请阅读以获得更多详情。

UTF-8

UTF-8是一个可变长度的代码。 一些字符需要1个字节,一些需要2个,3个和4个字符。每个字符的字节都是一个接一个地连续写入的字节stream。

虽然有些UTF-8字符可以是4个字节,但UTF-8 不能编码2 ^ 32个字符 。 它甚至不是很接近。 我会试着解释这个原因。

读取UTF-8数据stream的软件只是得到一个字节序列,应该如何判断接下来的4个字节是单个4字节字符还是2个2字节字符还是4个1字节字符一些其他的组合)? 基本上这是通过确定某些1字节的序列是不是有效的字符,某些2字节的序列是无效的字符来完成的,依此类推。 当出现这些无效序列时,假定它们构成较长序列的一部分。

你已经看到了一个相当不同的例子,我敢肯定:这就是所谓的逃避。 在许多编程语言中,决定string源代码中的\字符不会转换为string“编译”forms中的任何有效字符。 当在源中find\时,假定它是更长序列的一部分,如\n\xFF 。 请注意\x是一个无效的2个字符的序列,而\xF是一个无效的3个字符的序列,但\xFF是一个有效的4个字符的序列。

基本上,有很多字符和较短的字符之间的权衡。 如果您需要2 ^ 32个字符,则平均需要4个字节。 如果你想要所有的字符都是2个字节或更less,那么你不能有超过2 ^ 16个字符。 UTF-8给出了一个合理的折中scheme:所有的ASCII字符(ASCII 0到127)都给出了1个字节的表示,这对兼容性很好,但是允许更多的字符。

像大多数可变长度编码一样,包括上面所示的转义序列types,UTF-8是一个即时编码 。 这意味着,解码器只是逐字节地读取数据,一旦达到字符的最后一个字节,它就知道字符是什么(它知道它不是长字符的开始)。

例如,字符“A”用字节65表示,并且没有两个/三/四字节的字符,其第一字节是65.否则,解码器将不能将这些字符与“A “其次是别的。

但UTF-8更受限制。 它确保了较短字符的编码永远不会出现在较长字符编码的任何地方 。 例如,4字节字符中的字节都不能是65。

由于UTF-8具有128个不同的1字节字符(字节值为0-127),因此所有2,3和4字节字符必须由128-256范围内的字节组成。 这是一个很大的限制。 但是,它允许以字节为导向的string函数很less或不需要修改。 例如,如果其input是有效的UTF-8string,C的strstr()函数总是按预期工作。

UTF-16

UTF-16也是一个可变长度的代码; 其字符消耗2或4个字节。 0xD800-0xDFFF范围内的2字节值保留用于构造4字节字符,所有4字节字符由范围为0xD800-0xDBFF的两个字节组成,后跟2个字节,范围为0xDC00-0xDFFF。 因此,Unicode不会在U + D800-U + DFFF范围内分配任何字符。

UTF-32

UTF-32是一个固定长度的代码,每个字符长度为4个字节。 虽然这允许编码2 ^ 32个不同的字符,但是只允许0到0x10FFFF之间的值。

容量比较:

  • UTF-8: 2,097,152(实际上是2,166,912,但由于devise细节,其中一些映射到相同的东西)
  • UTF-16: 1,112,064
  • UTF-32: 4,294,967,296(但仅限于前面的1,114,112)

最受限制的是UTF-16! 正式的Unicode定义已经将Unicode字符限制为可以使用UTF-16编码的那些字符(即,范围U + 0000到U + 10FFFF,不包括U + D800到U + DFFF)。 UTF-8和UTF-32支持所有这些字符。

实际上UTF-8系统“人为”限制在4个字节。 它可以扩展到8个字节,而不会违反前面概述的限制,这将产生2 ^ 42的容量。 原来的UTF-8规范实际上允许多达6个字节,其容量为2 ^ 31。 但RFC 3629将其限制为4个字节,因为需要多less才能涵盖UTF-16的所有function。

还有其他的(主要是历史的)Unicode编码scheme,尤其是UCS-2(它只能将U + 0000编码到U + FFFF)。

UTF-8,UTF-16和UTF-32都支持全套的unicode代码点。 没有一个字符是由一个而不是另一个支持的。

至于奖金问题“这些编码是否可以扩展支持的字符数量不同?” 是和不是。 UTF-8和UTF-16编码的方式将它们可以支持的代码点总数限制在2 ^ 32以内。 但是,Unicode联盟不会将代码点添加到无法用UTF-8或UTF-16表示的UTF-32。 这样做违反了编码标准的精神,并且不能保证从UTF-32到UTF-8(或UTF-16)的一对一映射。

如果有疑问,我个人总是会检查Joel的关于unicode,编码和字符集的文章 。

所有的UTF-8/16/32编码都可以映射所有的Unicode字符。 请参阅维基百科的Unicode编码比较 。

这篇IBM文章用UTF-8对XML文档进行编码是非常有用的,并且表明如果您有select,最好selectUTF-8。 主要原因是工具支持很广泛,UTF-8 通常可以通过不知道unicode的系统。

从“ IBM 规范”中的规范部分可以看出

W3C和IETF最近都变得越来越坚持selectUTF-8,首先,最后,有时只是。 万维网1.0的W3C字符模型:基础指出:“当需要唯一的字符编码时,字符编码必须是UTF-8,UTF-16或UTF-32。US-ASCII向上兼容UTF- 8(US-ASCIIstring也是一个UTF-8string,参见[RFC 3629]),因此,如果需要与US-ASCII兼容,UTF-8就是合适的。 实际上,与US-ASCII的兼容性非常有用,这几乎是一个要求。 W3C明智地解释说:“在其他情况下,如API,UTF-16或UTF-32可能更合适。select其中一个的可能原因包括内部处理效率和与其他stream程的互操作性。

正如大家所说,UTF-8,UTF-16和UTF-32都可以对所有的Unicode代码点进行编码。 但是,UCS-2(有时被错误地称为UCS-16)变体不能,而这是你在Windows XP / Vista中发现的

请参阅维基百科获取更多信息。

编辑:我错了Windows,NT是唯一支持UCS-2的。 但是,许多Windows应用程序将像UCS-2中的每个代码点一样假设一个单词,因此您可能会发现错误。 看另一个维基百科文章 。 (感谢JasonTrue)