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

UTF-8,UTF-16和UTF-32

如何解决《UTF-8,UTF-16和UTF-32》经验,为你挑选了10个好方法。

UTF-8,UTF-16和UTF-32有什么区别?

我知道他们都将存储Unicode,并且每个都使用不同的字节数来表示字符.选择一个优于另一个是否有优势?



1> AnthonyWJone..:

UTF-8在ASCII字符代表文本块中的大多数字符的情况下具有优势,因为UTF-8将所有字符编码为8位(如ASCII).还有利的是,仅包含ASCII字符的UTF-8文件具有与ASCII文件相同的编码.

UTF-16在ASCII不占优势的地方更好,因为它主要使用每个字符2个字节.对于高阶字符,UTF-8将开始使用3个或更多字节,对于大多数字符,UTF-16仅保留2个字节.

UTF-32将覆盖4个字节中的所有可能字符.这让它变得非常臃肿.我想不出使用它有什么好处.


UTF-32优势:您不需要将存储的数据解码为32位Unicode代码点,例如逐字符处理.代码点已经在您的数组/向量/字符串中可用.
声明*"UTF-8将所有字符编码为8位"*是**错**.它不会**将*"全部"*字符编码为8位.它使用可变长度编码,它是8位的倍数.所以字符可以采用8,16,24,最多32位!
@richq您不能在UTF-32中进行逐字符处理,因为代码点并不总是与字符对应.
好吧,UTF-8在网络传输方面具有优势 - 不需要担心字节顺序,因为你一次传输一个字节的数据(而不是4).
如果(天堂帮助你)你必须重新实现轮子,也更容易解析.
UTF-32的优势:与utf-8等效相比,字符串操作可能更快
@TimČas谈论代码点,而不是字形.在offset中定位代码点是utf-8中非常密集的操作,因为它需要完全迭代,并且"跳转"为2> 4个字节,而utf-32具有实际的随机访问.子串操作因此更快.相反,如你所说,定位字形需要在两种编码中完全遍历,但在utf-32中将需要较少的跳转.
这句话有点令人困惑:"UTF-8将所有字符编码为8位".

2> Adam Rosenfi..:

简而言之:

UTF-8:可变宽度编码,向后兼容ASCII.ASCII字符(U + 0000到U + 007F)取1个字节,代码点U + 0080到U + 07FF取2个字节,代码点U + 0800到U + FFFF取3个字节,代码点U + 10000到U + 10FFFF需要4个字节.适合英文文本,不太适合亚洲文字.

UTF-16:可变宽度编码.代码点U + 0000到U + FFFF需要2个字节,代码点U + 10000到U + 10FFFF需要4个字节.英文文本不好,适合亚洲文字.

UTF-32:固定宽度编码.所有代码点都占用四个字节.巨大的记忆力,但快速操作.很少用.

长:请参阅维基百科:UTF-8,UTF-16和UTF-32.


@spurrymoses:我严格指的是数据字节占用的空间量.UTF-8每个亚洲字符需要3个字节,而UTF-16每个亚洲字符只需要2个字节.这确实不是一个主要问题,因为与计算机内存中存储的平均文本量相比,计算机现在拥有大量内存.
"UTF8对亚洲文本不是那么好"怎么样?这是错误的.例如,UTF-8非常适合日本人.我运行一个日本网站,所有内容都以UTF8编码,一切正常.UTF-8可以编码任何Unicode字符.
如果有人说在包含那些不能编码Unicode的编码格式的上下文中,UTF-8"对亚洲文本不太好",那么它们当然是错误的.但这不是背景.内存需求的上下文来自这样一个事实:问题(和答案)是比较UTF-8,UTF-16和UTF-32,它们都将编码亚洲文本但使用不同数量的内存/存储.因此,它们的相对优点自然完全在记忆要求的背景下."不太好"!="不好".
UTF-32不再使用了......在osx和linux`wchar_t`默认为4个字节.gcc有一个选项`-fshort-wchar`,它将大小减小到2个字节,但打破了与std libs的二进制兼容性.
@UstamanSangat是的,如果这个答案仅限于内存要求,那么我就错过了这一点.然而,这一点从未在答案中提出(问题也不需要它).那么看起来,我错过了一个从未做过的观点,但是你甚至在没有它的情况下能够看到它.当有人说UTF-8"对亚洲文本不太好"时 - 并没有将其限制在内存要求的上下文中,那就错了.
@PandaWood of source UTF-8可以编码任何角色!但是你有没有将内存需求与UTF-16的内存需求进行比较?你好像错过了这一点!
@McGafter:当然有.如果您想要值得信赖,请直接前往[The Unicode Consortium](http://www.unicode.org/versions/Unicode6.3.0/)的马口.有关UTF-*编码的说明,请参见第2.5章.但是为了获得对编码的简单,高级的理解,我发现维基百科的文章是一个更容易接近的来源.
UTF-16工作的原因是U + D800-U + DFFF留在代理对对的BMP中作为间隙.聪明.
Wikipedia指出,在现实世界中,由于文本中仍使用空格或英文单词,即使使用非英文字符,UTF-8的尺寸仍比UTF-16小。
尽管大多数亚洲字符的UTF-8占用3个字节,而UTF-16的占用为2个字节(一些常用的汉字最终出现在多语言平面中,在UTF-8和UTF-16中它们都占用4个字节),实际上并没有太大的区别,因为实际文档中经常混入大量ASCII字符。有关一个真实文档的并排大小比较,请参见http://utf8everywhere.org/#asian:UTF-8实际上花了* 50与UTF-16相比,用于编码日语HTML页面(日本的Wikipedia文章,日语)的字节数减少了%*。

3> Quassnoi..:

UTF-8可变1到4个字节.

UTF-16是可变的2或4个字节.

UTF-32固定为4个字节.


UTF8实际上是1到6个字节.
@Urkle不,UTF-8不能是5或6个字节.Unicode代码点限制为21位,将UTF-8限制为4个字节.(你当然可以扩展UTF-8的原则来编码任意大整数,但它不是Unicode.)参见RFC 3629.
引用维基百科:2003年11月,UTF-8受到RFC 3629的限制,以匹配UTF-16字符编码的约束:明确禁止对应于高和低代理字符的代码点,删除超过3%的三字节序列,以U + 10FFFF结束,删除了超过48%的四字节序列和所有五字节和六字节序列.
@Urkle在技术上是正确的,因为映射全范围的UTF32/LE/BE包括U-00200000-U-7FFFFFFF,即使Unicode v6.3以U-0010FFFF(包括端点)结束.这里有一个很好的细分如何加/减5和6字节utf8:https://lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html
用相关的参考零件及其来源备份这些?

4> jalf..:

Unicode定义了一个巨大的字符集,为每个图形符号分配一个唯一的整数值(这是一个主要的简化,实际上并不是真的,但它足够接近这个问题的目的).UTF-8/16/32只是对此进行编码的不同方式.

简而言之,UTF-32为每个字符使用32位值.这允许他们为每个角色使用固定宽度的代码.

UTF-16默认使用16位,但这只能为您提供65k个可能的字符,这对于完整的Unicode集来说已经足够了.所以一些字符使用16位值对.

UTF-8默认使用8位值,这意味着127个第一个值是固定宽度的单字节字符(最高有效位用于表示这是多字节序列的开始,留下7个实际字符值的位).所有其他字符编码为最多4个字节的序列(如果存储器服务).

这导致了我们的优势.任何ASCII字符都与UTF-8直接兼容,因此对于升级旧版应用程序,UTF-8是一种常见且明显的选择.在几乎所有情况下,它也将使用最少的内存.另一方面,您无法保证角色的宽度.它可能是1,2,3或4个字符宽,这使得字符串操作变得困难.

UTF-32是相反的,它使用最多的内存(每个字符是固定的4字节宽),但另一方面,你知道每个字符都有这个精确的长度,因此字符串操作变得更加简单.您可以根据字符串的字节长度计算字符串中的字符数.你不能用UTF-8做到这一点.

UTF-16是一种妥协.它允许大多数字符符合固定宽度的16位值.因此,只要您没有中文符号,音符或其他符号,就可以假设每个字符都是16位宽.它使用的内存比UTF-32少.但它在某种程度上是"两个世界中最糟糕的".它几乎总是使用比UTF-8更多的内存,它仍然无法避免困扰UTF-8(可变长度字符)的问题.

最后,与平台支持的内容一起使用通常很有帮助.Windows在内部使用UTF-16,因此在Windows上,这是显而易见的选择.

Linux有所不同,但它们通常使用UTF-8来处理符合Unicode的所有内容.

如此简短的回答:所有三种编码都可以编码相同的字符集,但它们将每个字符表示为不同的字节序列.


@tchrist:是的,这是不准确的.问题是要准确地解释Unicode,你需要编写数千页.我希望得到基本概念来解释编码之间的区别
说Unicode为每个**图形符号**分配一个唯一的整数是不准确的.它将这样分配给每个代码点,但是一些代码点是**不可见的控制字符**,而一些图形符号需要**多个代码点**来表示.

5> rook..:

Unicode是一个标准,关于UTF-x,您可以将其视为一些实际用途的技术实现:

UTF-8 - " 大小优化 ":最适合基于拉丁字符的数据(或ASCII),每个字符只需1个字节,但大小相应增加符号种类(在最坏的情况下,每个字符最多可增加6个字节)

UTF-16 - " 平衡 ":每个字符至少需要2个字节,这对于现有的主流语言集来说已经足够了,它具有固定的大小以便于字符处理(但是大小仍然是可变的,并且每个字符可以增长到4个字节)

UTF-32 - " 性能 ":允许使用简单算法作为固定大小字符(4字节)的结果,但存在内存缺点



6> Maroun..:

我试着在我的博文中给出一个简单的解释.

UTF-32

需要32位(4字节)来编码任何字符.例如,为了使用此方案表示"A"字符代码点,您需要以32位二进制数写入65:

00000000 00000000 00000000 01000001 (Big Endian)

如果仔细观察一下,你会发现使用ASCII方案时,最右边的7位实际上是相同的位.但由于UTF-32是固定宽度方案,我们必须附加三个额外的字节.这意味着如果我们有两个只包含"A"字符的文件,一个是ASCII编码的,另一个是UTF-32编码的,它们的大小相应地是1个字节和4个字节.

UTF-16

许多人认为,由于UTF-32使用固定宽度32位来表示代码点,因此UTF-16的固定宽度为16位.错误!

在UTF-16中,代码点可以用16位或32位表示.所以这个方案是可变长度编码系统.与UTF-32相比有什么优势?至少对于ASCII,文件的大小不会是原始文件的4倍(但仍然是两倍),因此我们仍然不能向后兼容ASCII.

由于7位足以表示"A"字符,因此我们现在可以使用2个字节而不是像UTF-32那样的4个字节.它看起来像:

00000000 01000001
UTF-8

你猜对了..在UTF-8中,代码点可以用32,16,24或8位表示,而作为UTF-16系统,这个也是可变长度编码系统.

最后,我们可以用与ASCII编码系统相同的方式表示"A":

01001101

一个小例子,其中UTF-16实际上优于UTF-8:

考虑中文字母"语" - 其UTF-8编码为:

11101000 10101010 10011110

虽然它的UTF-16编码更短:

10001010 10011110

为了理解表示及其解释方式,请访问原始帖子.



7> Jeff Adamson..:

UTF-8

没有字节顺序的概念

每个字符使用1到4个字节

ASCII是兼容的编码子集

完全自同步,例如,流中任何地方的丢弃字节最多会损坏一个字符

几乎所有欧洲语言都以每个字符两个字节或更少的字节编码

UTF-16

必须使用已知的字节顺序进行解析或读取字节顺序标记(BOM)

每个字符使用2或4个字节

UTF-32

每个字符都是4个字节

必须使用已知的字节顺序进行解析或读取字节顺序标记(BOM)

除非大部分字符来自CJK(中文,日文和韩文)字符空间,否则UTF-8将是最节省空间的.

UTF-32最适合通过字符偏移随机访问字节数组.


@KorayTugay有效的较短字节字符串从不用于较长的字符.例如,ASCII在0-127范围内,这意味着所有单字节字符都具有二进制形式的"0xxxxxxx".所有双字节字符以"110xxxxx"开头,第二个字节为"10xxxxxx".因此,假设两个字节字符的第一个字符丢失了.一旦你看到没有前面的'110xxxxxx`的`10xxxxxx`,你可以确定一个字节丢失或损坏,并丢弃该字符(或从服务器或其他任何地方重新请求它),然后继续前进直到你再看一个有效的第一个字节.

8> vartec..:

在UTF-32中,所有字符都用32位编码.优点是您可以轻松计算字符串的长度.缺点是对于每个ASCII字符,您浪费了额外的三个字节.

在UTF-8字符具有可变长度时,ASCII字符以一个字节(八位)编码,大多数西方特殊字符以两个字节或三个字节编码(例如€是三个字节),并且更多奇特的字符可以占用到四个字节.明显的缺点是,先验你无法计算字符串的长度.但与UTF-32相比,编码拉丁(英语)字母文本所需的字节数要少得多.

UTF-16也是可变长度的.字符以两个字节或四个字节编码.我真的没有看到这一点.它具有可变长度的缺点,但没有像UTF-8那样节省空间的优点.

在这三个中,显然UTF-8是最广泛传播的.



9> Farid Movsum..:

我做了一些测试来比较MySQL中UTF-8和UTF-16之间的数据库性能.

更新速度

UTF-8

在此输入图像描述

UTF-16

在此输入图像描述

插入速度

在此输入图像描述

在此输入图像描述

删除速度

在此输入图像描述

在此输入图像描述



10> mghie..:

根据您的开发环境,您甚至可能无法选择内部使用的字符串数据类型的编码.

但是对于存储和交换数据,我总是使用UTF-8,如果你有选择的话.如果您主要拥有ASCII数据,这将为您提供最少量的数据传输,同时仍然可以对所有内容进行编码.优化最少的I/O是现代机器的发展方向.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有