根据Wikipedia UTF-8页面,我听到人们的意见不一致。
他们是同一回事,不是吗?有人可以澄清吗?
根据Wikipedia UTF-8页面,我听到人们的意见不一致。
他们是同一回事,不是吗?有人可以澄清吗?
Answers:
为了扩展其他人给出的答案:
我们有很多语言和许多字符,计算机应该理想地显示这些字符。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。由于UTF-8中的单位大小与ASCII中的单位大小相同,因此HTTP之类的通信协议往往最适合UTF-8,并且大多数此类协议都是在ASCII时代设计的。另一方面,UTF-16 在代表所有活动语言时可提供最佳的平均空间/处理性能。
Unicode标准定义的代码点少于32位表示的代码点。因此,出于所有实际目的,UTF-32和UCS4成为相同的编码,因为您不必在UTF-32中处理多单位字符。
希望填写一些细节。
0x04000000
to到字符空间0x7FFFFFFF
,或者以二进制形式存在1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
-,实际上是6个字节。但是,最大为6个字节,而不是因为该文章令人困惑地声称“六个字节或更多 ”。
让我用一个例子来说明这个话题:
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
PS:如果您想在python中学习此主题,请单击此处
0
则字符由1 位表示(当前位);如果字节以位开头,110
则字符由2个字节表示(当前位和下一个(10
))后面的剩余位,如果字节1110
以3 开头,则该字符由3个字节表示,即当前字节和接下来的2个字节(后面的剩余位10
)。
不幸的是,根据上下文,“ 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的一些参考:
它们不是一回事-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)
http://www.wikiwand.com/en/UTF-8#/Description
看看第一行。
现有的答案已经解释了很多细节,但这是一个简短的答案,其中包含最直接的说明和示例。
Unicode是将字符映射到代码点的标准。
每个字符都有一个唯一的代码点(标识号),这是一个数字,例如9731。
UTF-8是一种在 编码的码点。
为了将所有字符存储在磁盘上(在文件中),UTF-8将字符分成最多4个八位字节(8位序列)-字节。UTF-8是几种编码(表示数据的方法)之一。例如,在Unicode中,(十进制)代码点9731表示一个雪人(☃
),它由UTF-8中的3个字节组成:E2 98 83
世界各地有很多字符,例如“ $,&,h,a,t,?,张,1,=,+ ...”。
然后是一个致力于这些角色的组织,
他们制定了一个称为“ Unicode”的标准。
标准如下:
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?...”
UTF-8是一种可能的Unicode编码方案文本。
统一码是一种广泛的标准,它定义了130,000个字符并为每个字符分配一个数字代码(一个代码点)。它还定义了有关如何对该文本进行排序,对其进行规范化,更改其大小写等的规则。Unicode中的字符由从零到0x10FFFF(含零)的代码点表示,尽管有些代码点是保留的,不能用于字符。
字符串Unicode代码点可以被编码成二进制流的方式不止一种。这些称为“编码”。最简单的编码是UTF-32,它简单地将每个代码点存储为32位整数,每个宽度为4个字节。
UTF-8是另一种编码,由于与UTF-32等相比具有许多优点,因此已成为事实上的标准。UTF-8编码为单字节值序列。每个代码点可以使用可变数量的这些字节值。ASCII范围内的代码点被裸编码,以与ASCII兼容。超出此范围的代码点使用可变数量的字节(2、3或4),具体取决于它们位于的范围。
UTF-8在设计时考虑了以下属性:
ASCII字符的编码方式与ASCII完全相同,因此ASCII字符串也是有效的UTF-8字符串。
二进制排序:使用朴素的二进制排序对UTF-8字符串进行排序仍将导致所有代码点均按数字顺序排序。
需要多个字节的字符不包含ASCII范围内的任何字节值,以确保它们的一部分不会被误认为ASCII字符。这也是一项安全功能。
UTF-8易于验证,并且可以通过验证器与其他字符编码区分开。其他8位或多字节编码的文本也很少会验证为UTF-8。
随机访问:在UTF-8字符串中的任何一点上,都可以判断该位置的字节是否是一个字符的第一个字节,并可以找到下一个或当前字符的开始,而无需向前扫描或向后超过几个字节,或者在流的开头读取任何内容。
他们是同一回事,不是吗?
不,不是。
我认为您所引用的Wikipedia页面的第一句话给出了一个不错的简短摘要:
UTF-8是一种可变宽度的字符编码,能够使用1到4个8位字节来编码Unicode中的所有1,112,064个有效代码点。
详细说明:
Unicode是一种标准,它定义了从字符到数字的映射,即所谓的代码点,(如下面的示例所示)。有关完整的映射,您可以在这里查看。
! -> U+0021 (21),
" -> U+0022 (22),
\# -> U+0023 (23)
UTF-8是在编码这些代码点的方式之一的形式的计算机可以理解的,又名比特。换句话说,这是一种将这些代码点中的每一个转换为比特序列或将一系列比特转换为等效代码点的方法/算法。请注意,有许多其他的Unicode编码。
乔尔给出了一个非常好的解释和历史的概况这里。
如果我可以总结一下我从该线程收集的信息:
Unicode将字符“转换” 为序数(十进制形式)。
à = 224
UTF-8是一种将这些数字 “转换” 为二进制表示形式的编码。
224 = 11000011 10100000
请注意,我们正在谈论的是224 的二进制表示形式,而不是其二进制形式,即0b11100000。
本文介绍了所有详细信息 http://kunststube.net/encoding/
写缓冲区
如果您あ
使用UTF8编码写入4字节缓冲区(符号),则二进制文件将如下所示:
00000000 11100011 10000001 10000010
如果您あ
使用UTF16编码写入4字节缓冲区(符号),则二进制文件将如下所示:
00000000 00000000 00110000 01000010
如您所见,根据内容中使用的语言,这将相应地影响您的记忆。
例如,对于该特定符号:あ
UTF16编码效率更高,因为我们有2个备用字节可用于下一个符号。但这并不意味着您必须对日本字母使用UTF16。
从缓冲区读取
现在,如果您想读取上述字节,则必须知道其写入的编码方式并正确解码。
例如,如果将以下代码解码:
00000000 11100011 10000001 10000010
转换为UTF16编码,则结果将臣
不是あ
注意:编码和Unicode是两件事。Unicode是很大的(表),每个符号都映射到一个唯一的代码点。例如,あ
符号(字母)的(代码点)为:30 42(十六进制)。另一方面,编码是一种在存储到硬件时将符号转换为更合适方式的算法。
30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.
30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.