当前位置:  开发笔记 > 编程语言 > 正文

UTF-8,UTF-16和UTF-32可以存储的字符数不同吗?

如何解决《UTF-8,UTF-16和UTF-32可以存储的字符数不同吗?》经验,为你挑选了4个好方法。

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

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

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



1> Artelius..:

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

UTF-8

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

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

UTF-32

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).


标记正确的答案似乎是错误的.这个答案实际上给出了数字,并且在解释中非常彻底.很棒的答案+1

2> 小智..:

不,它们只是不同的编码方法.它们都支持对同一组字符进行编码.

UTF-8使用每个字符一到四个字节的任何位置,具体取决于您编码的字符.ASCII范围内的字符只占用一个字节,非常不寻常的字符占用四个字符.

UTF-32每个字符使用四个字节,无论它是什么字符,因此它总是使用比UTF-8更多的空间来编码相同的字符串.唯一的优点是您可以通过仅计算字节数来计算UTF-32字符串中的字符数.

UTF-16对大多数字符使用两个字节,对于不常见字符使用四个字节.

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


@Joschuaᴜᴛꜰ-8&ᴜᴛꜰ-16是***同时***()找到ᵗʰ角色; 只有ᴜᴛꜰ-32是().这个危险,普遍和有害的问题困扰着所有违反*抽象信封的程序系统* - 所以代码猴子在ᴜᴛꜰ-16代码单元上弄脏他们的FᴜᴍʙʟᴇMɪᴛᴢᴇɴ而不是纯粹的抽象代码点.人们*经常*搞砸了; ᴇɢ:在Java中**总是使用**`String.codePointCount`,`String.codePointAt`,&ᶜ - **从不使用**`String.length`,`String.charAt`,&ᶜ.看看所有Java的默认值是ꜰᴜʙᴀʀ?使用ᴜᴛꜰ-8‖ᴜᴛꜰ-32,或者去ᴍᴀᴅ交易w /ᴜᴛꜰ-16的idioᵗsyncracies.
@Arafangion UTF-8不会为Unicode代码点提供5或6个字节.在Unicode之外编码代码点的定义是过时的而不是标准的UTF-8.
您可以通过计算字符串的长度来计算UTF-32字符串中_code points_的数量.这与_user感知的字符_不同,因为某些字符可以使用多个代码点.
略有不正确 - UTF-8使用每个字符一到六个*字节之间的任何位置,具体取决于您编码的字符.
"因此它总是使用比UTF-8更多的空间" - 你的意思是更多或相等的空间.

3> Derek Park..:

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)的一对一映射.



4> Atanas Korch..:

我个人总是在有疑问时检查Joel关于unicode,编码和字符集的帖子.


为什么不检查unicode.org,这可以从实际上正确的事情中获益.
推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有