根据维基百科的UTF-8页面,我听到了人们的相互矛盾的意见.
他们是一回事,不是吗?有人可以澄清吗?
扩大其他人给出的答案:
我们有很多语言,其中包含许多计算机应该理想显示的字符.Unicode为每个字符分配唯一的编号或代码点.
计算机处理诸如字节之类的数字......在此处跳过一些历史记录并忽略内存寻址问题,8位计算机将8位字节视为硬件上容易表示的最大数字单元,16位计算机将扩展到两个字节,依此类推.
诸如ASCII之类的旧字符编码来自(预)8位时代,并试图将当时计算中的主导语言(即英语)塞入0到127(7位)的数字中.字母表中有26个字母,包括资本和非资本形式,数字和标点符号,效果很好.对于其他非英语语言,ASCII扩展了第8位,但此扩展提供的额外128个数字/代码点将根据显示的语言映射到不同的字符.ISO-8859标准是此映射的最常见形式; ISO-8859-1和ISO-8859-15(也称为ISO-Latin-1,latin1,是的,还有两种不同版本的8859 ISO标准).
但是当你想用多种语言表示字符时,这还不够,所以将所有可用的字符塞进一个字节中是行不通的.
基本上有两种不同类型的编码:一种是通过添加更多位来扩展值范围.这些编码的示例是UCS2(2字节= 16位)和UCS4(4字节= 32位).它们与ASCII和ISO-8859标准本质上存在相同的问题,因为它们的值范围仍然有限,即使限制非常高.
另一种类型的编码使用每个字符可变数量的字节,并且最常见的编码是UTF编码.所有UTF编码的工作方式大致相同:您选择单位大小,UTF-8为8位,UTF-16为16位,UTF-32为32位.然后,标准将这些位中的一些定义为标志:如果它们被设置,则单元序列中的下一个单元将被视为相同字符的一部分.如果它们未设置,则此单位完全代表一个字符.因此,最常见的(英语)字符仅占用UTF-8中的一个字节(UTF-16中的两个,UTF-32中的4个),但是其他语言字符可以占用六个字节或更多.
多字节编码(我应该说上面解释后的多单元)具有相对节省空间的优点,但是查找子字符串,比较等操作的缺点都是必须将字符解码为unicode代码可以执行此类操作之前的点(但有一些快捷方式).
UCS标准和UTF标准都对Unicode中定义的代码点进行编码.从理论上讲,这些编码可用于编码任何数字(在编码支持的范围内) - 但当然这些编码用于编码Unicode代码点.这就是你们之间的关系.
Windows将所谓的"Unicode"字符串作为UTF-16字符串处理,而大多数UNIX默认为UTF-8.HTTP等通信协议往往最适合UTF-8,因为UTF-8中的单位大小与ASCII相同,大多数此类协议都是在ASCII时代设计的.另一方面,UTF-16 在表示所有生活语言时提供最佳的平均空间/处理性能.
Unicode标准定义的代码点数少于32位代表的代码点数.因此,出于所有实际目的,UTF-32和UCS4成为相同的编码,因为您不太可能必须处理UTF-32中的多单元字符.
希望填写一些细节.
不幸的是,"Unicode"以各种不同的方式使用,具体取决于上下文.它最正确的用法(IMO)是一个编码字符集 - 即一组字符和字符之间的映射以及表示它们的整数代码点.
UTF-8是一种字符编码 - 一种从字节序列转换为字符序列的方法,反之亦然.它涵盖了整个Unicode字符集.ASCII被编码为每个字符一个字节,其他字符根据其确切的代码点占用更多字节(对于所有当前定义的代码点最多4个字节,即高达U-0010FFFF,实际上4个字节可以应对U型001FFFFF).
当"Unicode"用作字符编码的名称(例如,作为.NET Encoding.Unicode属性)时,它通常表示UTF-16,它将最常见的字符编码为两个字节.某些平台(特别是.NET和Java)使用UTF-16作为其"本机"字符编码.如果您需要担心无法在单个UTF-16值中编码的字符(它们被编码为"代理对"),这会导致毛病问题 - 但大多数开发人员从不担心这一点,IME.
关于Unicode的一些参考:
Unicode联盟网站,特别是教程部分
乔尔的文章
我自己的文章 (面向.NET)
让我用一个例子来说明这个主题:
A chinese character: ? it's unicode value: U+6C49 convert 6C49 to binary: 01101100 01001001
到目前为止,没有什么神奇的,它非常简单.现在,让我们说我们决定将这个角色存储在我们的硬盘上.为此,我们需要以二进制格式存储字符.我们可以简单地将其存储为'01101100 01001001'.完成!
但等一下,是'01101100 01001001'一个字符还是两个字符?你知道这是一个角色,因为我告诉过你,但是当一台电脑读到它时,它根本不知道.因此,我们需要某种"编码"来告诉计算机将其视为一种.
这就是'UTF-8'规则的来源:http://www.fileformat.info/info/unicode/utf8.htm
Binary format of bytes in sequence 1st Byte 2nd Byte 3rd Byte 4th Byte Number of Free Bits Maximum Expressible Unicode Value 0xxxxxxx 7 007F hex (127) 110xxxxx 10xxxxxx (5+6)=11 07FF hex (2047) 1110xxxx 10xxxxxx 10xxxxxx (4+6+6)=16 FFFF hex (65535) 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (3+6+6+6)=21 10FFFF hex (1,114,111)
根据上表,如果我们想使用'UTF-8'格式存储这个字符,我们需要在字符前加上一些'标题'.我们的中文字符长度为16位(自己计算二进制值),因此我们将使用第3行的格式,因为它提供了足够的空间:
Header Place holder Fill in our Binary Result 1110 xxxx 0110 11100110 10 xxxxxx 110001 10110001 10 xxxxxx 001001 10001001
将结果写在一行:
11100110 10110001 10001001
这是中文字符的UTF-8(二进制)值!(自己确认一下:http://www.fileformat.info/info/unicode/char/6c49/index.htm)
A chinese character: ? it's unicode value: U+6C49 convert 6C49 to binary: 01101100 01001001 embed 6C49 as UTF-8: 11100110 10110001 10001001
它们不是一回事 - UTF-8是一种编码Unicode的特殊方式.
根据您的应用程序和您打算使用的数据,您可以选择许多不同的编码.据我所知,最常见的是UTF-8,UTF-16和UTF-32.
Unicode仅定义代码点,即表示字符的数字.如何将这些代码点存储在内存中取决于您使用的编码.UTF-8是编码Unicode字符的一种方法,以及许多其他字符.
Unicode是一种标准,它与ISO/IEC 10646一起定义了通用字符集(UCS),它是表示几乎所有已知语言所需的所有现有字符的超集.
Unicode为其指令表中的每个字符分配一个名称和一个数字(字符代码或代码点).
UTF-8编码,是一种在计算机内存中以数字方式表示这些字符的方法.UTF-8将每个代码点映射为八位字节序列(8位字节)
例如,
UCS字符= Unicode汉字
UCS代码点= U + 24B62
UTF-8编码= F0 A4 AD A2(十六进制)= 11110000 10100100 10101101 10100010(bin)
Unicode只是一种标准,用于定义字符集(UCS)和编码(UTF)以对此字符集进行编码.但一般来说,Unicode是指字符集而不是标准.
在5分钟内完全阅读每个软件开发人员绝对必须知道的关于Unicode和字符集(没有借口!)和Unicode 的绝对最低要求.
现有的答案已经解释了很多细节,但这里有一个非常简短的答案,最直接的解释和例子.
Unicode是将字符映射到代码点的标准.
每个字符都有一个唯一的代码点(标识号),这是一个像9731的数字.
UTF-8是一种在 编码的码点.
为了将所有字符存储在磁盘上(在文件中),UTF-8将字符分成最多4个八位字节(8位序列) - 字节.UTF-8是几种编码之一(表示数据的方法).例如,在Unicode中,(十进制)代码点9731表示一个snowman(?
),它由UTF-8中的3个字节组成:E2 98 83
这是一个带有一些随机例子的排序列表.
世界上有很多角色,比如"$,&,h,a,t,?,张,1,=,+ ......".
然后有一个致力于这些角色的组织,
他们制定了一个名为"Unicode"的标准.
标准如下:
创建一个表单,其中每个位置称为"代码点"或"代码位置".
整个位置从U + 0000到U + 10FFFF;
到目前为止,一些位置充满了字符,其他位置被保存或为空.
例如,位置"U + 0024"填充有字符"$".
PS:当然还有另一个名为ISO的组织维持另一个标准 - "ISO 10646",几乎相同.
如上所述,U + 0024只是一个位置,因此我们无法在计算机中为"$"保存"U + 0024".
必须有一种编码方法.
然后是编码方法,如UTF-8,UTF-16,UTF-32,UCS-2 ....
在UTF-8下,代码点"U + 0024"被编码为00100100.
00100100是我们在计算机中为"$"保存的值.
我已经检查了Gumbo的答案中的链接,我想在这里粘贴这些东西的一部分也存在于Stack Overflow上.
"...有些人误以为Unicode只是一个16位代码,每个字符占16位,因此有65,536个可能的字符.这实际上并不正确.这是关于Unicode的最常见的神话,所以如果你这么想,不要心疼.
事实上,Unicode有一种不同的思考角色的方式,你必须要理解Unicode的思维方式,否则就没有意义.
到目前为止,我们假设一个字母映射到一些可以存储在磁盘或内存中的位:
A - > 0100 0001
在Unicode中,字母映射到称为代码点的东西,这仍然只是一个理论概念.代码点如何在内存或磁盘上呈现,这是另一个故事......"
"...每个字母表中的每个柏拉图字母都由Unicode联盟分配一个幻数,编号如下:U + 0639.这个幻数称为代码点.U +表示"Unicode",数字为十六进制. U + 0639是阿拉伯字母Ain.英文字母A是U + 0041 ...."
"......好的,所以说我们有一个字符串:
你好
在Unicode中,它对应于这五个代码点:
U + 0048 U + 0065 U + 006C U + 006C U + 006F.
只是一堆代码点.数字,真的.我们还没有说过如何将其存储在内存中或在电子邮件中表示......"
"......这就是编码进来的地方.
关于Unicode编码的最早的想法导致了关于这两个字节的神话,嘿,让我们将这些数字分别存储在两个字节中.所以,你好变成
00 48 00 65 00 6C 00 6C 00 6F
对?没那么快!不可能是:
48 00 65 00 6C 00 6C 00 6F 00?......"