好的.我知道这看起来像典型的"为什么他不只是谷歌它或去www.unicode.org并查找它?" 问题,但对于这样一个简单的问题,在检查了两个来源之后,答案仍然存在.
我很确定所有这三种编码系统都支持所有Unicode字符,但我需要在演示文稿中声明之前确认它.
奖金问题:这些编码在可以扩展到支持的字符数量方面是否有所不同?
没有Unicode字符可以存储在一个编码中而不能存储在另一个编码中.这只是因为有效的Unicode字符被限制为可以存储在UTF-16中的内容(UTF-16具有三种编码中最小的容量).换句话说,UTF-8和UTF-32 可用于表示比UTF-16更广泛的字符,但它们不是.请阅读以获得更多详情.
UTF-8是可变长度代码.一些字符需要1个字节,一些字符需要2个字节,一些字符串需要3个字节.每个字符的字节只是作为连续的字节流一个接一个地写入.
虽然一些UTF-8字符长度可以是4个字节,但UTF-8 不能编码2 ^ 32个字符.它甚至都不是很接近.我会试着解释一下这个的原因.
读取UTF-8流的软件只获取一个字节序列 - 如何判断接下来的4个字节是单个4字节字符,还是两个2字节字符,或者4个1字节字符(或者其他一些组合)?基本上这是通过确定某些1字节序列不是有效字符,并且某些2字节序列不是有效字符来完成的,依此类推.当出现这些无效序列时,假设它们构成较长序列的一部分.
你已经看到了一个相当不同的例子,我敢肯定:它被称为逃避.在许多编程语言中,决定\
字符串源代码中的字符不会转换为字符串"编译"形式中的任何有效字符.当在源中找到\时,它被假定为较长序列的一部分,如\n
或\xFF
.请注意,这\x
是一个无效的2个字符的序列,\xF
是一个无效的3个字符的序列,但它\xFF
是一个有效的4个字符的序列.
基本上,在具有多个字符和具有较短字符之间存在折衷.如果你想要2 ^ 32个字符,它们需要平均4个字节长.如果您希望所有字符都是2个字节或更少,那么您不能超过2 ^ 16个字符.UTF-8给出了合理的折衷方案:所有ASCII字符(ASCII 0到127)都给出了1字节的表示,这对兼容性很有帮助,但允许更多的字符.
与大多数可变长度编码一样,包括上面所示的转义序列,UTF-8是一个瞬时代码.这意味着,解码器只是逐字节读取,一旦到达字符的最后一个字节,它就知道字符是什么(并且它知道它不是更长字符的开头).
例如,字符'A'用字节65表示,并且没有两个/三/四字节字符,其第一个字节是65.否则解码器将无法区分这些字符而不是'A' '其次是别的东西.
但UTF-8受到进一步限制.它确保较短字符的编码永远不会出现在较长字符编码中的任何位置.例如,4字节字符中的所有字节都不能为65.
由于UTF-8有128个不同的1字节字符(字节值为0-127),因此所有2,3和4字节字符必须仅由128-256范围内的字节组成.这是一个很大的限制.但是,它允许面向字节的字符串函数在很少或不需要修改的情况下工作.例如,如果C的strstr()
输入是有效的UTF-8字符串,则C的函数始终按预期工作.
UTF-16也是可变长度代码; 它的字符消耗2或4个字节.0xD800-0xDFFF范围内的2字节值保留用于构造4字节字符,所有4字节字符由0xD800-0xDBFF范围内的两个字节组成,后跟0xDC00-0xDFFF范围内的2个字节.因此,Unicode不会分配U + D800-U + DFFF范围内的任何字符.
UTF-32是一个固定长度的代码,每个字符长度为4个字节.虽然这允许编码2 ^ 32个不同的字符,但在该方案中仅允许0到0x10FFFF之间的值.
UTF-8: 2,097,152(实际上是2,166,912,但由于设计细节,其中一些映射到同一个东西)
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个字节,因为这需要多少才能涵盖UTF-16的所有功能.
还有其他(主要是历史的)Unicode编码方案,特别是UCS-2(它只能编码U + 0000到U + FFFF).
不,它们只是不同的编码方法.它们都支持对同一组字符进行编码.
UTF-8使用每个字符一到四个字节的任何位置,具体取决于您编码的字符.ASCII范围内的字符只占用一个字节,非常不寻常的字符占用四个字符.
UTF-32每个字符使用四个字节,无论它是什么字符,因此它总是使用比UTF-8更多的空间来编码相同的字符串.唯一的优点是您可以通过仅计算字节数来计算UTF-32字符串中的字符数.
UTF-16对大多数字符使用两个字节,对于不常见字符使用四个字节.
http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings
UTF-8,UTF-16和UTF-32都支持全套unicode代码点.没有一个支持的字符而不支持另一个字符.
至于奖金问题"这些编码的字符数是否可以扩展到支持?" 是的,不是.UTF-8和UTF-16的编码方式将它们可以支持的代码点总数限制为小于2 ^ 32.但是,Unicode Consortium不会向UTF-32添加无法用UTF-8或UTF-16表示的代码点.这样做会违反编码标准的精神,并且无法保证从UTF-32到UTF-8(或UTF-16)的一对一映射.
我个人总是在有疑问时检查Joel关于unicode,编码和字符集的帖子.