UTF-8,UTF-16和UTF-32
UTF-8,UTF-16和UTF-32之间有什么区别?
我明白,他们将全部存储Unicode,并且每个使用不同数量的字节来表示一个字符。 select一个在另一个之上有好处吗?
在ASCII字符代表文本块中大多数字符的情况下,UTF-8具有优势,因为UTF-8将所有字符编码为8位(如ASCII)。 只有ASCII字符的UTF-8文件具有与ASCII文件相同的编码也是有利的。
在ASCII不占主导地位的情况下,UTF-16更好,因为它主要使用每个字符2个字节。 UTF-8将开始使用3个或更多的字节作为UTF-16保留在大多数字符的2个字节的高位字符。
UTF-32将覆盖4个字节的所有可能的字符。 这使得它很臃肿。 我想不出使用它有什么好处。
简而言之:
- 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 。
-
UTF-8是可变的1到4个字节。
-
UTF-16是可变的2或4个字节。
-
UTF-32固定4个字节。
Unicode定义了一个巨大的字符集,为每个graphics符号分配一个唯一的整数值(这是一个主要的简化,实际上并不是真实的,但对于这个问题来说足够接近)。 UTF-8/16/32是对此进行编码的简单方法。
简而言之,UTF-32为每个字符使用32位值。 这使得他们可以为每个angular色使用固定宽度的代码。
UTF-16在默认情况下使用16位,但只能提供65k个可能的字符,这对于完整的Unicode集合来说是远远不够的。 所以有些字符使用16位值对。
UTF-8默认使用8位值,这意味着127个第一个值是固定宽度的单字节字符(最高有效位用来表示这是一个多字节序列的开始,剩下7个位的实际字符值)。 所有其他字符被编码为最多4个字节(如果内存服务)的序列。
这导致我们的优势。 任何ASCII字符都与UTF-8直接兼容,因此为了升级旧版应用程序,UTF-8是一个常见而明显的select。 在几乎所有情况下,它也将使用最less的内存。 另一方面,你不能保证一个字符的宽度。 它可能是1,2,3或4个字符宽,这使得string操作困难。
UTF-32是相反的,它使用最多的内存(每个字符是一个固定的4字节宽),但另一方面,你知道每个字符都有这个精确的长度,所以string操作变得简单得多。 您可以简单地从string的字节长度计算string中的字符数。 你不能用UTF-8做到这一点。
UTF-16是一个妥协。 它允许大多数字符适合固定宽度的16位值。 所以只要你没有中文符号,音符或其他一些字符,就可以假定每个字符都是16位宽。 它使用比UTF-32更less的内存。 但在某些方面,这是“两全其美”。 它几乎总是比UTF-8使用更多的内存,它仍然不能避免困扰UTF-8(可变长度字符)的问题。
最后,平台支持的内容通常很有帮助。 Windows在内部使用UTF-16,所以在Windows上,这是明显的select。
Linux有所不同,但是他们通常使用UTF-8来处理符合Unicode的所有内容。
这么简单的答案:所有这三种编码都可以编码相同的字符集,但它们将每个字符表示为不同的字节序列。
Unicode是一种标准,而UTF-x在某些实际用途上可以认为是技术实现:
- UTF-8 – “ 尺寸优化 ”:最适合基于拉丁字符的数据(或ASCII),每个字符只需要1个字节,但尺寸随着符号的变化而变化(最坏的情况下,每个字符最多可增加6个字节)
- UTF-16 – “ 平衡 ”:每个字符最less需要2个字节,这对于现有的主stream语言来说已经足够了,因为它具有固定的大小,以便于字符处理(但是大小仍然是可变的,每个字符最多可以增长4个字节)
- UTF-32 – “ 性能 ”:允许使用简单的algorithm作为固定大小字符(4字节)的结果,但存储器不利
我试图在我的博文中给出一个简单的解释。
UTF-32
需要32位(4字节)来编码任何字符。 例如,为了使用这个scheme来表示“A”字符代码点,你需要在32位二进制数中写入65:
00000000 00000000 00000000 01000001 (Big Endian)
如果仔细看一下,你会注意到当使用ASCIIscheme时,最右边的7位实际上是相同的位。 但是由于UTF-32是固定宽度scheme ,我们必须附加三个额外的字节。 这意味着如果我们有两个只包含“A”字符的文件,一个是ASCII编码的,另一个是UTF-32编码的,它们的大小将分别为1个字节和4个字节。
UTF-16
很多人认为UTF-32使用固定宽度的32位来表示代码点,UTF-16是固定宽度的16位。 错误!
在UTF-16中,代码点可以用16位或32位表示。 所以这个scheme是可变长度编码系统。 与UTF-32相比有什么优势? 至less对于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
为了理解表示forms和解释方式,请访问原文。
我做了一些testing,比较MySQL中UTF-8和UTF-16之间的数据库性能。
更新速度
UTF-8
UTF-16
插入速度
删除速度
UTF-8
- 没有字节顺序的概念
- 每个字符使用1到4个字节
- ASCII是编码的兼容子集
- 完全自同步,例如,从一个stream中的任何位置丢弃的字节将最多损坏一个字符
- 几乎所有的欧洲语言都以每个字符两个字节或更less的字节编码
UTF-16
- 必须用已知的字节顺序parsing或读取字节顺序标记(BOM)
- 每个字符使用2或4个字节
UTF-32
- 每个字符是4个字节
- 必须用已知的字节顺序parsing或读取字节顺序标记(BOM)
除非大多数字符来自CJK(中文,日文和韩文)字符空间,否则UTF-8将是空间效率最高的。
UTF-32最适合随机访问字符偏移的字节数组。
在UTF-32中,所有字符都用32位编码。 好处是你可以很容易地计算出string的长度。 缺点是每个ASCII字符会浪费额外的三个字节。
在UTF-8字符长度可变,ASCII字符编码为一个字节(8位),大部分西方特殊字符编码为两个字节或三个字节(例如€是字节),更多的异国字符可以占用到四个字节。 明显的缺点是,先验你不能计算string的长度。 但是,与UTF-32相比,编写拉丁(英文)字母文本所需的字节less得多。
UTF-16也是可变长度的。 字符以两个字节或四个字节编码。 我真的不明白这一点。 它具有变长的缺点,但没有节省与UTF-8相同的空间。
在这三个中,显然UTF-8是最广泛传播的。
根据你的开发环境,你可能甚至没有select什么编码你的string数据types将在内部使用。
但是为了存储和交换数据,我总是使用UTF-8,如果你有select的话。 如果你主要使用ASCII数据,这将会给你传送最less量的数据,同时仍然能够编码所有的东西。 优化至lessI / O是现代机器的方式。
简而言之,使用UTF-16或UTF-32的唯一原因是分别支持非英文和古文字。
我想知道为什么有人会select非UTF-8编码,当它显然更有效的网页/编程的目的。
一个常见的误解 – 后缀数字并不表示其能力。 它们都支持完整的Unicode,只不过UTF-8可以用一个字节来处理ASCII码,所以对于CPU和互联网来说,效率更低/不易损坏。
一些很好的阅读: http : //www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html和http://utf8everywhere.org
如前所述,差异主要在于底层variables的大小,在每种情况下变得更大以允许表示更多的字符。
然而,字体,编码和事情是非常复杂的(不必要的?),所以需要一个大的链接来填写更多的细节:
http://www.cs.tut.fi/~jkorpela/chars.html#ascii
不要指望明白这一切,但如果你以后不想有任何问题,尽可能早地尽可能地学习(或者只是让其他人为你解决问题)。
保罗。