如果UTF-8是8位编码,为什么它需要1-4个字节?

时间:2011-06-14 04:07:07

标签: unicode encoding utf-8

在Unicode站点上写道,UTF-8可以用1-4个字节表示。据我所知,https://softwareengineering.stackexchange.com/questions/77758/why-are-there-multiple-unicode-encodings UTF-8是一个8位编码。 那么,真相是什么? 如果它是8位编码,那么ASCII和UTF-8之间有什么区别? 如果不是,那为什么它被称为UTF-8,为什么我们需要UTF-16和其他人如果他们占用相同的内存?

3 个答案:

答案 0 :(得分:15)

<强> The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) by Joel Spolsky - Wednesday, October 08, 2003

摘自上文:

  因而发明了UTF-8的精彩概念。 UTF-8是另一个系统,用于在内存中使用8位字节存储您的Unicode代码点串,即那些神奇的U +号。在UTF-8中,0-127的每个代码点都存储在一个字节中。仅使用2,3存储代码点128及以上,实际上最多6个字节。   这有一个很好的副作用,英文文本在UTF-8中与在ASCII中看起来完全相同,因此美国人甚至没有注意到任何错误。只有世界其他地方必须跳过篮球。具体来说,Hello,即U + 0048 U + 0065 U + 006C U + 006C U + 006F,将被存储为48 65 6C 6C 6F,不料!与存储在ASCII,ANSI和行星上的每个OEM字符集中的相同。现在,如果你如此大胆地使用重音字母或希腊字母或克林贡字母,你将不得不使用几个字节来存储单个代码点,但美国人永远不会注意到。 (UTF-8还有一个很好的属性,即无知的旧字符串处理代码,想要使用单个0字节,因为空终止符不会截断字符串)。

     

到目前为止,我已经告诉过你三种Unicode编码方式。传统的两字节存储方法称为UCS-2(因为它有两个字节)或UTF-16(因为它有16位),你还需要弄清楚它是否是高端UCS- 2或低端UCS-2。还有流行的新UTF-8标准,如果您有英语文本和脑死亡程序的完美巧合,并且完全没有意识到除了ASCII之外还有其他任何东西,那么它具有良好的性能,也很有效。

     

实际上还有很多其他的Unicode编码方式。有一种称为UTF-7的东西,它很像UTF-8,但保证高位总是为零,所以如果你必须通过某种严厉的警察状态电子邮件系统传递Unicode,认为7位是相当的够了,谢谢你仍然可以毫发无伤。有UCS-4,它以4个字节存储每个代码点,它具有很好的属性,每个代码点可以以相同的字节数存储,但是,即使是德克萨斯人也不会那么大胆浪费那么多记忆。

     

事实上,现在你正在考虑用Unicode代码点表示的柏拉图理想字母,这些unicode代码点也可以用任何旧式编码方案编码!例如,您可以使用ASCII编码Hello(U + 0048 U + 0065 U + 006C U + 006C U + 006F)的Unicode字符串,或旧的OEM希腊语编码,或希伯来语ANSI编码,或几百种编码中的任何一种编码到目前为止已经发明了,只有一个问题:一些字母可能不会出现!如果您尝试在编码中尝试表示的Unicode代码点没有等价物,那么通常会得到一个小问号:?或者,如果你真的很好,一个盒子。你得到了什么? - &GT;

     

有数百种传统编码只能正确存储一些代码点,并将所有其他代码点更改为问号。一些流行的英文文本编码是Windows-1252(西欧语言的Windows 9x标准)和ISO-8859-1,也称为Latin-1(对任何西欧语言都有用)。但是试着在这些编码中存储俄语或希伯来语字母,你会得到一堆问号。 UTF 7,8,16和32都具有能够正确存储任何代码点的良好属性。

答案 1 :(得分:12)

'8位'编码意味着编码的各个字节使用8位。相反,纯ASCII是7位编码,因为它只有代码点0-127。过去,软件在8位编码方面存在问题; Base-64和uuencode编码的原因之一是通过不处理8位编码的电子邮件系统获取二进制数据。然而,它已经持续了十年或更长时间,因为它不再是一个问题 - 软件必须是8位清理,或者能够处理8位编码。

Unicode本身是一个21位字符集。它有很多编码:

  • UTF-32,其中每个Unicode代码点都存储在32位整数
  • UTF-16,其中许多Unicode代码点存储在一个16位整数中,但有些需要两个16位整数(因此每个Unicode代码点需要2或4个字节)。
  • UTF-8,其中Unicode代码点可能需要1,2,3或4个字节来存储单个Unicode代码点。

因此,“UTF-8可以用1-4个字节表示”可能不是最恰当的表达方式。 “Unicode代码点可以用UTF-8中的1-4个字节表示”更合适。

答案 2 :(得分:11)

UTF-8是一个8位可变宽度编码。 Unicode中的前128个字符,当用UTF-8编码表示时,表示为ASCII中的字符。

为了进一步理解这一点,Unicode将字符视为代码点 - 仅仅可以用多种方式表示的数字(编码)。 UTF-8就是这样一种编码。它是最常用的,因为它在所有编码中提供了最佳的空间消耗特性。如果以UTF-8编码存储ASCII字符集中的字符,则UTF-8编码数据将占用相同的空间量。这允许以前使用ASCII的应用程序无缝地移动(好吧,不一定,但肯定不会产生像Y2K这样的东西)到Unicode,因为字符表示是相同的。

我将在RFC 3629中提供有关UTF-8编码如何工作的摘录:

   Char. number range  |        UTF-8 octet sequence
      (hexadecimal)    |              (binary)
   --------------------+---------------------------------------------
   0000 0000-0000 007F | 0xxxxxxx
   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

你会注意到为什么编码会导致字符占用1到4个字节(右边的列),用于Unicode(左栏)中不同的字符范围。

UTF-16,UTF-32,UCS-2等将采用不同的编码方案,其中代码点表示为16位或32位代码,而不是UTF-8的8位代码。