UTF-8和Unicode有什么区别?

733

我听到了许多人的不同意见 - 根据维基百科 UTF-8页面。

它们不是一个东西吗?有人能澄清一下吗?


1
这个WIKI关于Unicode和UTF的写法我认为还不错。其中一些评论有点奇怪:“在UTF-8(或任何其他多字节编码)中,可以在字符中间拆分或截断字符串,这可能导致无效字符串。”因此,一个被UTF-8编码的字符串不再是一个字符串,而是一个字节数组或字节流。组成字符串的字符被编码了。当然,它也可以被解码。当然,你可以在起始字节或后续字节之后剪切utf-8序列,但是为什么有人要这样做呢? - brighty
1
这篇关于字符串数据类型的文章非常有教育意义:https://mortoray.com/2013/11/27/the-string-type-is-broken/ -- 有时候在处理字符串及其字节级组件时,您可能会无意中将一个字符切成两半。 - Everett
如果该字节流正在通过网络进行分组传输,则字符串可能会被拆分成两个数据包 - 即在不是UTF-8边界(即下一个字节不是具有MSBits为011011101111010的字节)的地方。@brighty - SlySven
@SlySven 你是在讨论字节流还是字符串?当然,一个字节流可以被分成两个数据包,但这是TCP的工作,在目标端重新组合这个谜题,例如每个数据包都有其序列号,接收方会确认每个已接收的数据包。当然,如果TCP/IP会话不正常断开连接,则只有部分 - 比如UTF-8编码的字节流 - 到达目的地。 - brighty
我主要为MUD客户端应用编写代码,在缺少额外的(所谓的“Go-Ahead”或“End-of-record”)信号的情况下,数据包在穿越互联网时可能会被分割 - 如果客户端没有等待足够长的时间以获取任何进一步的数据包... - SlySven
18个回答

638

对其他人所给出的答案进行补充:

我们有很多语言,其中包含许多计算机理想显示的字符。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中的多单元字符。
希望这些细节能填补一些空缺。

13
从概念上讲,UCS-2和UCS-4是字符集,而不是字符编码(因此得名)。 - Mechanical snail
92
此帖子中存在许多错误。ISO 8859不止有两个版本。ASCII不能用于英语,无法处理卷曲引号、分币符、重音符号等等,Unicode不仅仅是非英语所需要的!在任何编码中,没有代码点占用超过4个字节;这个6字节的说法是完全错误的。正如此文所述,不能UTF编码任何Unicode标量值:代理项和其他66个非字符都被禁止使用。UCS-4和UTF-32并不相同。不存在多单元UTF-32。UTF-16并不像他们所声称的那样高效。&c&c&c! - tchrist
2
ASCII也不包含英镑符号£,当然也不包含欧元符号€(比ASCII年轻得多)。 - TRiG
3
@tchrist看起来6个字节并不是不可思议的了。请参考这篇文章:http://www.joelonsoftware.com/articles/Unicode.html,其中指出从`0x04000000`到`0x7FFFFFFF`有一个字符空间,并且在二进制中它是 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - 这确实是6个字节。然而,6个字节是最大值,而不是该文章所混淆地声称的“六个或更多字节”。 - syntaxerror
15
“只有代码点128及以上才会使用2个、3个,甚至最多6个字节进行存储”这句话在最初写出来时是准确的,但那一年晚些时候(12年前),它被否定了。http://en.wikipedia.org/wiki/UTF-8上写道:“最初的规范涵盖了高达31位的数字(通用字符集的原始限制)。在2003年11月,为了匹配UTF-16字符编码的限制,UTF-8被RFC 3629限制在U+10FFFF处结束。这删除了所有5个和6个字节的序列,以及大约一半的4个字节的序列。” - Mooing Duck
显示剩余6条评论

454
让我用一个例子来阐述这个话题:
A Chinese character:      
its Unicode value:        U+6C49
convert 6C49 to binary:   01101100 01001001

没有什么神奇的,很简单。现在,假设我们决定将这个字符存储在我们的硬盘上。为了做到这一点,我们需要以二进制格式存储该字符。我们可以简单地将其存储为'01101100 01001001'。完成!
但是等一下,'01101100 01001001'是一个字符还是两个字符?你知道这是一个字符,因为我告诉了你,但是当计算机读取它时,它并不知道。所以我们需要一些编码规则来告诉计算机将其视为一个字符。
这就是UTF-8的规则发挥作用的地方:https://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二进制值!亲自看看吧:https://www.fileformat.info/info/unicode/char/6c49/index.htm

摘要

A Chinese character:      汉
its Unicode value:        U+6C49
convert 6C49 to binary:   01101100 01001001
encode 6C49 as UTF-8:     11100110 10110001 10001001

P.S. 如果你想在Python中学习这个主题,点击这里

8
“等等,‘01101100 01001001’ 是一个字符还是两个字符呢?你知道这是一个字符是因为我告诉了你,但是当计算机读取它时,它并不知道。因此,我们需要某种“编码”来告诉计算机把它视为一个字符。” 好的,但是计算机仍然不知道它应该使用UTF-8进行编码吗? - Koray Tugay
40
计算机不知道它应该使用哪种编码。当你将一个字符保存到文件中时,你必须告诉计算机它要使用的编码方式;同样地,当你从文件中读取一个字符时,也需要告诉计算机它所采用的编码方式。 - Cheng
6
@Connor 计算机不知道使用什么格式。当您保存文档时,文本编辑器必须显式设置其编码为utf-8或用户想要使用的任何格式。同样,当文本编辑器程序读取文件时,它需要选择一个文本编码方案来正确解码。当您输入字母时,情况也是如此,文本编辑器需要知道您使用的编码方式,以便正确保存它。 - Cheng
3
那这些标头是如何被解释的呢?如果我看第一张表,那么我的理解是:如果字节以位“0”开头,则该字符由1个字节(当前字节)表示;如果字节以“110”开头,则该字符由2个字节(当前字节和下一个字节(在“10”后剩余的位))表示;如果字节以“1110”开头,则该字符由3个字节(当前字节和接下来的2个字节(在“10”后剩余的位))表示。 - JBoy
31
阅读10篇关于UTF-8的文章后,我在10秒内就理解了。 - jrhee17
显示剩余3条评论

247

"Unicode"被不同的上下文以不同的方式使用。在我看来,它最正确的用法是作为一种编码字符集 - 即一个字符集和将字符映射为整数代码点的映射。

UTF-8是一种字符编码方式,用于将字节序列转换为字符序列以及反向转换。它覆盖了整个Unicode字符集。ASCII字符编码为每个字符一个字节,而其他字符则根据其精确的代码点采用更多的字节(对于所有当前定义的代码点,即U-0010FFFF以内的字符,最多需要4个字节;实际上,4个字节可以处理U-001FFFFF以内的字符)。

当"Unicode"作为字符编码的名称使用时(例如.NET Encoding.Unicode属性),它通常表示UTF-16,该编码将大部分常见字符编码为两个字节。某些平台(特别是.NET和Java)使用UTF-16作为其“本地”字符编码。如果您需要考虑无法用单个UTF-16值编码的字符(它们会被编码为"代理对"),这会导致混乱的问题 - 但是大多数开发人员从不关心这个,以我的经验来看。

Unicode的一些参考资料:


21
我认为UTF-16只在Windows平台上等同于“Unicode”。人们倾向于在*nix上默认使用UTF-8。虽然如此,还是很好的回答。 - jalf
10
@Chris:不,ISO-8859-1不是UTF-8。UTF-8将U+0080到U+00FF编码为两个字节,而不是一个字节。Windows 1252和ISO-8859-1在大部分情况下是相同的,但是它们在值为0x80到0x99之间有所不同,如果我没记错的话,ISO 8859-1有一个“空洞”,但CP1252定义了字符。 Translated: @Chris: 不,ISO-8859-1不等同于UTF-8。UTF-8将U+0080到U+00FF编码为两个字节,而不是一个字节。Windows 1252 和 ISO-8859-1在大多数情况下相似,但它们在0x80到0x99之间的值有所区别(如果我没记错),其中ISO 8859-1有一个“空洞”,而CP1252定义了这些字符。 - Jon Skeet
13
将UTF-16称为“Unicode”这个想法让我感到不安,因为它有可能会产生混淆,即使这显然只是.NET约定。UTF-16是表示Unicode的一种方式,但它并不是“Unicode编码”。 - thomasrutter
7
UTF-8不需要代理对,它只是使用逐渐变长的字节序列来表示非BMP字符。 - Jon Skeet
5
是的,“Unicode”在Windows中通常不幸地被用来表示“UTF-16”。 - Jon Skeet
显示剩余11条评论

129

它们不是同一件事 - UTF-8 是一种特定的 Unicode 编码方式。

根据您的应用程序和所使用的数据,可以选择许多不同的编码方式。据我所知,最常见的有 UTF-8、UTF-16 和 UTF-32。


14
然而,关键是一些编辑建议将文件保存为“Unicode”或“UTF-8”。因此,在这种情况下提到“Unicode”,我认为是指UTF-16,是必要的。 - serhio

104

Unicode只定义了码点,即表示字符的数字。如何将这些码点存储在内存中取决于您使用的编码方式。 UTF-8是一种编码Unicode字符的方式,有许多其他方式。


3
然而,重点是一些编辑建议将文件保存为“Unicode”或“UTF-8”。因此,在这种情况下提到“Unicode”的意思是UTF-16,我认为是必要的。 - serhio
一个数字,它表示ASCII中的字符。 - brighty

42
Unicode是一个标准,与ISO/IEC 10646一起定义了包含几乎所有已知语言所需的所有现有字符的超集——通用字符集(UCS)。Unicode为其库中的每个字符分配名称和编号(字符代码或码点)。
UTF-8编码是一种将这些字符数字化表示于计算机内存中的方式。UTF-8将每个代码点映射到一系列八位字节的序列。
例如:
UCS字符 = Unicode汉字 UCS码点 = U+24B62
UTF-8编码 = F0 A4 AD A2(十六进制)= 11110000 10100100 10101101 10100010(二进制)

不,UTF-8仅将代码点映射到大于127的序列中。从0到127的所有内容都不是序列,而是单个字节。顺便说一下,ASCII也将字符名称分配给数字,因此这与Unicode所做的相同。但是,Unicode不止到代码点127,而是一直到0x10ffff。 - brighty
2
@brightly 我有不同的看法。Ascii字符确实映射到单个字节序列。第一个位,在Ascii字符代码的情况下为0,表示后面跟随的字节数为零。请查看第一行。http://www.wikiwand.com/en/UTF-8#/Description - nightlytrails
对我来说,序列由多个字节组成。UTF-8中的ASCII字符是一个单独的字节,最高位设置为0。高于127的码点需要序列,始终具有起始字节和一个、两个或三个后续字节。那么,为什么你要称一个单独的字节为“序列”呢? - brighty
嗯...很多时候,英语律师会因软件中的故意误用而感到困惑。这里也是一样的情况。你可以就此争论,但这并不会使它更加清晰明了。 - nightlytrails
2
@brighty 嗯,数学上,一个0序列是可以的。这里也可以有一个1元素的序列。 - chux - Reinstate Monica
@chux 当使用 utf-8 并存储只占用一个字节的 ASCII 字符时,我们仍然可以称其为 utf-8 序列。实际上,utf-8 经常被解释为一个字节序列,无论该序列包含多少个字符。 - brighty

32
UTF-8是一种用于Unicode文本的编码方案。在许多情况下,特别是在网络上,它正在成为最受支持和最知名的Unicode文本编码,并且是JSON和XML中默认使用的文本编码。
Unicode是一个广泛范围的标准,定义了超过149,000个字符,并为每个字符分配了一个数字代码(代码点)。它还定义了对这些文本进行排序、规范化、更改大小写等的规则。Unicode中的字符由从零到0x10FFFF(包括)的代码点表示,尽管某些代码点被保留,不能用于字符。
Unicode代码点字符串可以以多种方式编码为二进制流。这些被称为"编码"。最直接的编码是UTF-32,它简单地将每个代码点存储为32位整数,每个代码点占用4个字节的宽度。由于代码点只到0x10FFFF(需要21位),因此这种编码有些浪费。
UTF-8是另一种编码方式,由于一些优势而在其他编码方式中获得了广泛的应用。UTF-8将每个码点编码为1、2、3或4个字节序列。ASCII范围内的码点被编码为单个字节值,使其与ASCII完全兼容。超出此范围的码点根据其所在的范围使用2、3或4个字节。UTF-8的设计考虑了以下特性:
  • 在UTF-8编码中,ASCII编码中存在的字符以与ASCII相同的方式进行编码,因此任何ASCII字符串自然也是一个有效的UTF-8字符串,表示相同的字符。

  • 更高效:UTF-8中的文本字符串几乎总是比UTF-32或UTF-16中的相同字符串占用更少的空间,只有少数例外。

  • 二进制排序:使用二进制排序对UTF-8字符串进行排序仍然会导致所有代码点按照数字顺序排序。

  • 当一个代码点使用多个字节时,这些字节中没有一个(甚至是第一个字节)包含ASCII范围内的值,确保它们的任何部分都不会被误认为是ASCII字符。这是一个重要的安全特性,特别是在使用最初设计为8位编码的系统中使用UTF-8编码文本时。

  • 可以轻松验证UTF-8以确保其为有效的UTF-8。其他8位或多字节编码的文本很少会因为UTF-8的特定结构而偶然验证为UTF-8。

  • 随机访问:在UTF-8字符串的任何位置,可以确定该位置的字节是否是一个字符的第一个字节,以及找到下一个或当前字符的起始位置,而无需向前或向后扫描超过3个字节或知道我们从字符串的哪个位置开始读取。


几个小问题:[1] “ASCII字符的编码方式与ASCII中完全相同”不应该改为“ASCII字符的编码方式与UTF-8中完全相同”吗? [2] 短语“Unicode中的代码...”不太清楚(对我来说)。你是指“Unicode代码点”吗? - skomisa
@skomisa,对于第一点,我的意思是ASCII和UTF-8在ASCII范围内字符的编码是相同的。 - thomasrutter
对于第二点,那是一个很好的观点,我会进行编辑以使其更清晰。 - thomasrutter
关于您最近的编辑,https://tonsky.me/blog/unicode/ 引用了170,000个分配的代码点。 - undefined
1
@tripleee 我认为这归结于代码点和字符之间的差异 - 你的数字可能包括用于私有使用或替代编码的代码点,而我的只是字符。我的来源是Unicode.org的常见问题解答,截至Unicode 15,是正确的。 - undefined
以下是你可能感兴趣的字符统计数据链接:https://www.unicode.org/versions/stats/charcountv15_0.html - undefined

26

1
@serhio:我知道。虽然有三种不同的UTF-16编码:两个显式的UTF-16LEUTF-16BE,以及隐式的UTF-16,其中字节序通过BOM指定。 - Gumbo
@Gumbo:缺少BOM并不意味着它是不同的编码。只有两种编码。 - Mooing Duck

25

现有的答案已经解释了很多细节,但这里是一个非常简短的答案,带有最直接的解释和示例。

Unicode是将字符映射到代码点的标准。
每个字符都有一个唯一的代码点(识别号),它是像9731这样的数字。

UTF-8是代码点的编码之一。
为了将所有字符存储在磁盘上(在文件中),UTF-8将字符分成最多4个八位字节序列 - 字节。 UTF-8是多种编码(表示数据的方法)之一。例如,在Unicode中,(十进制)代码点9731代表雪人(),在UTF-8中由3个字节表示:E2 98 83

这里是一个随机示例的排序列表


19

在阅读了关于这个话题的众多帖子和文章之后,我得出了以下解释:

1 - Unicode字符表

"Unicode"是一个巨大的表格,它有21位宽度,这21位提供了1,114,112个代码点/值/字段/位置来存储字符。

在这1,114,112个代码点中,有1,111,998个可以存储Unicode字符,因为有2048个代码点被保留为代理项,还有66个代码点被保留为非字符。因此,有1,111,998个代码点可以存储独特的字符、符号、表情等。

然而,截至目前,这1,114,112个代码点中只有144,697个被使用。这144,697个代码点包含了覆盖所有语言、符号、表情等的字符。

每个字符在“Unicode”中都被分配了一个特定的码点,也就是一个特定的值/Unicode编号。例如,字符“❤”使用了1,114,112个码点中的一个。它的值(即Unicode编号)是“U+2764”。这是一个由两个字节组成的十六进制码点,以二进制表示为00100111 01100100。但是为了表示这个码点,UTF-8编码使用了3个字节(24位),以二进制表示为11100010 10011101 10100100(不包括两个空格字符,每个字符使用1位,我只是为了可视化目的添加了它们,所以请忽略它们)。
现在,我们的计算机如何知道这3个字节“11100010 10011101 10100100”是要单独读取还是一起读取?如果将这3个字节单独读取然后转换为字符,结果将是“Ô, Ø, ñ”,与我们的心形表情符号“❤”相差甚远。
2 - 编码标准(UTF-8、ISO-8859、Windows-1251等)
为了解决这个问题,人们发明了编码标准。其中最流行的是UTF-8,自2008年以来。UTF-8占据了平均97.6%的网页,这就是为什么我们将在下面的示例中使用UTF-8的原因。
2.1 - 什么是编码?
编码简单地说就是将一种东西转换成另一种东西。在我们的例子中,我们将数据转换成UTF-8格式,更具体地说是将字节转换成UTF-8字节。虽然这句话在技术上可能不正确,但我想重新表达一下。
2.2 关于UTF-8格式的一些信息,以及它为什么如此重要
UTF-8使用最少1个字节来存储一个字符,最多4个字节。多亏了UTF-8格式,我们可以拥有占用超过1个字节的字符。
这非常重要,因为如果不是UTF-8格式,我们就无法拥有如此丰富多样的字母表,因为一些字母表的字母无法适应1个字节。我们也无法拥有表情符号,因为每个表情符号至少需要3个字节。我相信你现在已经明白了,所以让我们继续向前。
2.3 将中文字符编码为UTF-8的示例
现在,假设我们有一个中文字符"汉"。
这个字符正好占据16个二进制位"01101100 01001001",因此正如我们上面讨论的,我们无法读取这个字符,除非我们将其编码为UTF-8,因为计算机无法知道这两个字节是要单独读取还是一起读取。
将这个"汉"字符的2个字节转换为我所称的UTF-8字节,结果如下:
(普通字节)"01101100 01001001" ->(UTF-8编码字节)"11100110 10110001 10001001"
现在,我们是怎么从2个字节变成3个字节的呢?这怎么能算是UTF-8编码,把2个字节变成3个呢?
为了解释UTF-8编码的工作原理,我将直接复制@MatthiasBraun的回答,非常感谢他出色的解释。
2.4 UTF-8编码实际上是如何工作的?
我们这里有一个将字节编码为UTF-8的模板。这就是编码发生的方式,如果你问我,这非常令人兴奋!
现在,请仔细看一下下面的表格,然后我们一起来解读它。
        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)

上表中的"x"字符代表"Free Bits"的数量,这些位是空的,我们可以向它们写入数据。
其他位被保留用于UTF-8格式,它们被用作标头/标记。通过这些标头,在使用UTF-8编码读取字节时,计算机知道哪些字节需要一起读取,哪些需要单独读取。
字符经过UTF-8编码后的字节大小取决于需要写入的位数。
在我们的例子中,"汉"字符正好是2个字节或16位:"01101100 01001001",因此经过UTF-8编码后,我们的字符大小将为3个字节或24位:"11100110 10110001 10001001",因为"3个UTF-8字节"有16个Free Bits,我们可以向其写入数据。
解决方案如下所示,逐步进行。
2.5 解决方案:
        Header  Place holder    Fill in our Binary   Result         
        1110    xxxx            0110                 11100110
        10      xxxxxx          110001               10110001
        10      xxxxxx          001001               10001001 

2.6 总结:
        A Chinese character:      汉
        its Unicode value:        U+6C49
        convert 6C49 to binary:   01101100 01001001
        encode 6C49 as UTF-8:     11100110 10110001 10001001

3 - UTF-8、UTF-16和UTF-32之间的区别

UTF-8、UTF-16和UTF-32编码之间的主要区别在于它们在内存中表示一个字符所需的字节数:

UTF-8使用至少1个字节,但如果字符更大,则可以使用2、3或4个字节。UTF-8还与ASCII表兼容。

UTF-16使用至少2个字节。UTF-16不能使用3个字节,只能使用2个或4个字节。UTF-16与ASCII表不兼容。

UTF-32始终使用4个字节。

记住:UTF-8和UTF-16是可变长度编码,其中UTF-8可以占用1到4个字节,而UTF-16可以占用2或4个字节。UTF-32是一种固定宽度编码,它始终占用32位。

你怎么才能找到在Unicode中确切的2个字节或16位:01101100 01001001。我可以看到这张表吗? - Jin Lim
这比必要的要复杂得多。我在“值“U+2764”在二进制中看起来像这样:“11100010 10011101 10100100””时就已经迷失了。首先,不明显的是2764是十六进制的。其次,在二进制中应该是类似于00100111 01100100。实际上,这句话应该说:“U+2764是由两个字节组成的十六进制代码点。然而,为了表示这个代码点,UTF-8编码使用了3个字节。如何以及为什么UTF-8从00100111 0110010011100010 10011101 10100100的过程将在下文中解释。” - BenderBoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接