UTF-8,UTF-16和UTF-32有什么区别?
我知道它们都将存储Unicode,并且每个都使用不同数量的字节来表示字符。选择一个而不是另一个有优势吗?
UTF-8,UTF-16和UTF-32有什么区别?
我知道它们都将存储Unicode,并且每个都使用不同数量的字节来表示字符。选择一个而不是另一个有优势吗?
Answers:
在ASCII字符代表文本块中大多数字符的情况下,UTF-8具有一个优势,因为UTF-8将这些字符编码为8位(如ASCII)。还有利的是,仅包含ASCII字符的UTF-8文件具有与ASCII文件相同的编码。
UTF-16在ASCII不占优势的情况下更好,因为它主要每个字符使用2个字节。对于高阶字符,UTF-8将开始使用3个或更多字节,而对于大多数字符,UTF-16仅保留2个字节。
UTF-32将覆盖4个字节中的所有可能字符。这使它显得肿。我想不出使用它的任何优势。
简而言之:
wchar_t
默认为4字节。gcc有一个选项-fshort-wchar
,可以将大小减小到2个字节,但是破坏了与std libs的二进制兼容性。
UTF-8是1到4个字节的变量。
UTF-16是2或4个字节的变量。
UTF-32是固定的4个字节。
注意:UTF-8可以采用最新约定的1到6个字节:https : //lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html
Unicode定义了一个巨大的字符集,为每个图形符号分配了一个唯一的整数值(这是一个重大的简化,实际上并不正确,但是对于这个问题而言,它已经足够接近了)。UTF-8 / 16/32是对此进行编码的不同方法。
简而言之,UTF-32为每个字符使用32位值。这样一来,他们就可以为每个字符使用固定宽度的代码。
UTF-16默认情况下使用16位,但这只能为您提供65,000个可能的字符,对于完整的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略有不同,但是对于兼容Unicode的所有内容,它们通常都使用UTF-8。
答案很简短:所有三种编码都可以编码相同的字符集,但是它们将每个字符表示为不同的字节序列。
Unicode是一种标准,关于UTF-x,您可以将其视为一些实际目的的技术实现:
我试图在博客中给出一个简单的解释。
需要32位(4字节)来编码任何字符。例如,为了使用此方案表示“ A”字符代码点,您需要以32位二进制数写65:
00000000 00000000 00000000 01000001 (Big Endian)
如果仔细观察,您会注意到,使用ASCII方案时,最右边的7位实际上是相同的位。但是由于UTF-32是固定宽度方案,因此我们必须附加三个额外的字节。这意味着如果我们有两个仅包含“ A”字符的文件,一个文件是ASCII编码的,另一个文件是UTF-32编码的,则它们的大小将分别为1字节和4字节。
许多人认为,由于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中,代码点可以使用32位,16位,24位或8位表示,并且作为UTF-16系统,这也是可变长度编码系统。
最后,我们可以像使用ASCII编码系统一样来表示“ A”:
01001101
考虑中文字母“语”-其UTF-8编码为:
11101000 10101010 10011110
虽然其UTF-16编码较短:
10001010 10011110
为了理解表示形式及其解释方式,请访问原始帖子。
除非大多数字符都来自CJK(中文,日文和韩文)字符空间,否则UTF-8将是最节省空间的。
UTF-32最适合通过将字符偏移到字节数组中进行随机访问。
0xxxxxxx
二进制形式。所有两个字节的字符都110xxxxx
以第二个字节开始10xxxxxx
。因此,假设两个字节字符的第一个字符丢失了。一看到10xxxxxx
没有110xxxxxx
前置字符,您就可以确定一个字节是否丢失或损坏,并丢弃该字符(或从服务器或其他设备重新请求该字符),然后继续操作,直到再次看到一个有效的第一个字节。
我进行了一些测试,以比较MySQL中UTF-8和UTF-16之间的数据库性能。
在UTF-32中,所有字符都用32位编码。优点是您可以轻松计算字符串的长度。缺点是,对于每个ASCII字符,您都会浪费额外的三个字节。
在具有可变长度的UTF-8字符中,ASCII字符被编码为一个字节(八位),大多数西方特殊字符被编码为两个字节或三个字节(例如€为三个字节),并且更多的特殊字符可能会被占用到四个字节。明显的缺点是,先验不能计算字符串的长度。但是,与UTF-32相比,对拉丁(英语)字母文本进行编码所需的字节要少得多。
UTF-16的长度也是可变的。字符以两个字节或四个字节编码。我真的不明白这一点。它具有可变长度的缺点,但是没有节省像UTF-8一样多的空间的优点。
在这三者中,显然UTF-8是使用最广泛的。
根据您的开发环境,您甚至可能无法选择内部将使用哪种字符串数据类型的编码。
但是对于存储和交换数据,如果可以选择的话,我将始终使用UTF-8。如果您大部分都是ASCII数据,那么这将为您提供最少的数据传输量,同时仍然能够对所有内容进行编码。针对最少的I / O进行优化是在现代计算机上运行的方法。
如上所述,差异主要是基础变量的大小,在每种情况下,其变大以允许表示更多字符。
但是,字体,编码和事物非常复杂(不必要吗?),因此需要一个大链接来填充更多细节:
http://www.cs.tut.fi/~jkorpela/chars.html#ascii
不要指望全部理解,但是如果您以后不想遇到问题,则值得尽早学习(或只是让别人为您解决问题),尽可能多地学习。
保罗
简而言之,使用UTF-16或UTF-32的唯一原因是分别支持非英语和古代文字。
我想知道为什么有人会选择非UTF-8编码,因为它明显更有效地用于Web /编程目的。
一个常见的误解-带后缀的数字并不表示其功能。它们都支持完整的Unicode,只是UTF-8可以处理单个字节的ASCII,所以效率更高/对CPU和Internet的破坏更小。
一些不错的阅读:http : //www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html 和http://utf8everywhere.org