UTF-8和Unicode有什么区别

sar*_*ake 462 unicode encoding terminology utf-8 character-encoding

根据维基百科的UTF-8页面,我听到了人们的相互矛盾的意见.

他们是一回事,不是吗?有人可以澄清吗?

小智 457

扩大其他人给出的答案:

我们有很多语言,其中包含许多计算机应该理想显示的字符.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中的多单元字符.

希望填写一些细节.

  • @Tuukka这篇文章中的错误很多.ISO 8859不仅仅有2个版本.ASCII对英语不起作用,缺少卷曲引号,分号,重音符号以及更多内容 - Unicode不仅仅是非英语; 英语也需要它!**ANY**编码中没有代码点占用超过4个字节; 这个6字节的业务是完全错误的.您不能对任何Unicode标量值进行UTF编码,因为这样说:代理和其他66个非字符都是禁止的.UCS-4和UTF-32不一样.没有多单元UTF-32.UTF-16效率不如他们假装 - &c&c&c! (67认同)
  • @syntaxerror:"只使用2,3存储代码点128及以上,实际上最多6个字节." 写作时是准确的,但同年晚些时候(十二年前)它被宣告无效.http://en.wikipedia.org/wiki/UTF-8说"原始规范涵盖了最多31位的数字(通用字符集的原始限制).2003年11月,UTF-8被RFC 3629限制为以U + 10FFFF结束,以匹配UTF-16字符编码的约束.这删除了所有5字节和6字节序列,以及大约一半的4字节序列." (12认同)
  • 从概念上讲,UCS-2和UCS-4是*字符集*,而不是*字符编码*(因此名称). (9认同)
  • @tchrist:你会更详细地指出这些错误吗? (4认同)
  • ASCII 也不包含英镑符号 £,当然也不包含欧元符号 €(比 ASCII 年轻得多)。 (2认同)
  • 这是正确的,还是仍然充满错误? (2认同)
  • @tchrist 看起来 6 个字节 __are__ 毕竟不是不可能的。看到这个:http://www.joelonsoftware.com/articles/Unicode.html 表示有一个从`0x04000000`到`0x7FFFFFFF`的字符空间,或者在二进制中它是`1111110v 10vvvvvvv 10vvvvvvv 10vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv确实是6个字节。然而,6 个字节是 __maximum__,而不是像文章混淆地声称“六个字节 * 或更多 *”。 (2认同)

Jon*_*eet 199

不幸的是,"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-16在Windows平台上仅等于"Unicode".人们倾向于在*nix上默认使用UTF-8.虽然+1,很好的答案 (16认同)
  • 调用UTF-16"Unicode"的想法让我不安,因为它有可能混淆 - 尽管这只是一个.NET惯例.UTF-16是一种表示Unicode的方式,但它不是"Unicode编码". (13认同)
  • @Chris:不,ISO-8859-1不是*UTF-8.UTF-8将U + 0080编码为U + 00FF作为两个字节,而不是一个.Windows 1252和ISO-8859-1*大多数*相同,但如果我没记错的话,它们在值0x80和0x99之间不同,其中ISO 8859-1有一个"漏洞",但CP1252定义了字符. (10认同)
  • @unwesen:UTF-8不需要代理对.它只是使用逐渐变长的字节序列来表示非BMP字符. (6认同)
  • @RoyiNamir:是的,遗憾的是,"Unicode"通常用于表示"UTF-16",特别是在Windows中. (5认同)
  • 最后我听说,最大的Unicode代码点是U + 0010FFFF - 所以还有更大的增长空间.在我们必须将代理对移植到UTF-32之前还需要一段时间,因为接受的答案的作者似乎认为是这种情况.;-) (2认同)
  • @unwesen:我的观点是,与UTF-8和UTF-16不同,UTF-32一直是固定宽度编码,并且总是如此.无论是在BMP还是其中一个补充平面,每个代码点都由四个字节表示. (2认同)
  • 至于使用“Unicode”来表示 UTF-16,您是对的,Jon:这是 Microsoft 约定而不是 .NET 约定,我也讨厌它。如果没有 MS 将其所有客户暴露于这种公然错误的用法,这些东西就很难解释。 (2认同)
  • 在Unicode自己的术语中,**UTF**代表**Unicode转换格式**,所以他们更喜欢说**UTF-8**是**转换格式**而不是**字符编码**,由于许多人多年来以多种冲突的方式使用它,因此后一个术语变得含糊不清. (2认同)

Che*_*eng 199

让我用一个例子来说明这个主题:

A chinese character:      ?
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001
Run Code Online (Sandbox Code Playgroud)

到目前为止,没有什么神奇的,它非常简单.现在,让我们说我们决定将这个角色存储在我们的硬盘上.为此,我们需要以二进制格式存储字符.我们可以简单地将其存储为'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)
Run Code Online (Sandbox Code Playgroud)

根据上表,如果我们想使用'UTF-8'格式存储这个字符,我们需要在字符前加上一些'标题'.我们的中文字符长度为16位(自己计算二进制值),因此我们将使用第3行的格式,因为它提供了足够的空间:

Header  Place holder    Fill in our Binary   Result         
1110    xxxx            0110                 11100110
10      xxxxxx          110001               10110001
10      xxxxxx          001001               10001001
Run Code Online (Sandbox Code Playgroud)

将结果写在一行:

11100110 10110001 10001001
Run Code Online (Sandbox Code Playgroud)

这是中文字符的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
Run Code Online (Sandbox Code Playgroud)

  • @KorayTugay计算机不知道它应该使用什么编码.将字符保存到文件时以及从文件中读取字符时,必须告诉它. (14认同)
  • 阅读 10 篇关于 UTF-8 的文章;读完这篇我在 10 秒内就明白了:) (12认同)
  • "但等一下,是'01101100 01001001'一个字符或两个字符?你知道这是一个字符因为我告诉过你,但是当一台电脑读它时,它根本不知道.所以我们需要某种"编码"来告诉计算机将其视为一体." 好吧,但计算机仍然不知道它应该用utf-8编码吗? (6认同)
  • @Connor计算机不知道使用什么格式.保存文档时,文本编辑器必须将其编码显式设置为utf-8或用户想要使用的任何格式.此外,当文本编辑器程序读取文件时,它需要选择文本编码方案来正确解码它.当您输入并输入一个字母时,文本编辑器需要知道您使用的方案,以便正确保存它. (2认同)
  • 那么这些标题是如何解释的呢?如果我看第一个表,那么我认为:如果字节以"0"开头,则字符由1位(当前的1)表示,如果字节以"110"开头,则字符由2个字节表示(当前和下一个("10"之后的剩余位)),如果字节以"1110"开始,那么该字符由3个字节表示,当前和接下来的2个字节("10"之后的剩余位). (2认同)

Gre*_*reg 107

它们不是一回事 - UTF-8是一种编码Unicode的特殊方式.

根据您的应用程序和您打算使用的数据,您可以选择许多不同的编码.据我所知,最常见的是UTF-8,UTF-16和UTF-32.

  • 但是,关键是有些编辑建议将文件保存为"Unicode"或"UTF-8".所以在这种情况下提到的"Unicode"是UTF-16,我认为是必要的. (10认同)

Mar*_*ote 66

Unicode仅定义代码点,即表示字符的数字.如何将这些代码点存储在内存中取决于您使用的编码.UTF-8是编码Unicode字符的一种方法,以及许多其他字符.

  • 在查看本页面上的其他答案之前和之后阅读本文 (4认同)
  • 但是,关键是有些编辑建议将文件保存为"Unicode"或"UTF-8".所以在这种情况下提到的"Unicode"是UTF-16,我认为是必要的. (2认同)

nig*_*ils 30

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)

  • @brightly我不同.Ascii字符确实映射到单个字节序列.第一个位,在ascii字符的代码的情况下为0,表示后面有多少字节 - 零.`http:// www.wikiwand.com/en/UTF-8#/ Description`看看第一行. (2认同)
  • @brighty Hmmm,在数学中,[0 的序列](https://en.wikipedia.org/wiki/Sequence#Finite_and_infinite) 元素是可以的。1 个元素的序列在这里也可以。 (2认同)

Gum*_*mbo 24

Unicode只是一种标准,用于定义字符集(UCS)和编码(UTF)以对此字符集进行编码.但一般来说,Unicode是指字符集而不是标准.

在5分钟内完全阅读每个软件开发人员绝对必须知道的关于Unicode和字符集(没有借口!)Unicode 的绝对最低要求.


bas*_*ic6 22

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

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

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

这是一个带有一些随机例子排序列表.

  • @brighty:是的,但为什么"不!"?我写道"UTF-8是几种编码之一"*因为*还有UTF-16和UTF-32. (4认同)

tho*_*ter 19

UTF-8Unicode文本的一种可能的编码方案。

Unicode是一个范围广泛的标准,它定义了超过 140,000 个字符并为每个字符分配了一个数字代码(一个代码点)。它还定义了如何对文本进行排序、规范化、更改大小写等的规则。Unicode 中的字符由从零到 0x10FFFF 的代码点表示,但有些代码点是保留的,不能用于字符。

有不止一种方法可以将一串 Unicode 代码点编码为二进制流。这些被称为“编码”。最直接的编码是UTF-32,它只是将每个代码点存储为一个 32 位整数,每个编码点为 4 个字节宽。由于代码点最多只能达到 0x10FFFF(需要 21 位),因此这种编码有点浪费。

UTF-8是另一种编码,由于与 UTF-32 和其他编码相比有许多优势,它正在成为事实上的标准。UTF-8 将每个代码点编码为 1、2、3 或 4 字节值的序列。ASCII 范围内的代码点被编码为单字节值,以与 ASCII 兼容。此范围之外的代码点每个使用 2、3 或 4 个字节,具体取决于它们所在的范围。

UTF-8 的设计考虑了以下属性:

  • ASCII 字符的编码方式与 ASCII 完全相同,因此 ASCII 字符串也是表示相同字符的有效 UTF-8 字符串。

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

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

  • 当代码点使用多个字节时,这些字节都不包含 ASCII 范围内的值,确保它们的任何部分都不会被误认为是 ASCII 字符。这也是一个安全功能。

  • UTF-8 可以轻松验证,并通过验证器与其他字符编码区分开来。由于 UTF-8 的结构非常特殊,其他 8 位或多字节编码的文本也很少会被验证为 UTF-8。

  • 随机访问:在 UTF-8 字符串中的任何一点,都可以判断该位置的字节是否是字符的第一个字节,并可以找到下一个或当前字符的开头,而无需向前扫描或者向后超过 3 个字节,或者知道我们开始读取的字符串有多远。


小智 19

在阅读了有关该主题的大量帖子和文章后,我的解释是:

\n

1 - Unicode 字符表

\n

“Unicode”是一个巨大的表,即 21 位宽,这 21 位为 1,114,112 个代码点/值/字段/位置提供了存储字符的空间。

\n

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

\n

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

\n

“Unicode”中的每个字符都被分配给一个特定的代码点,也称为具有特定的值/Unicode 编号。例如,字符“\xe2\x9d\xa4”仅使用 1,114,112 个代码点中的一个代码点。它的值(也称为 Unicode 数字)为“U+2764”。这是一个由两个字节组成的十六进制代码点,用二进制表示为 00100111 01100100。但是为了表示这个代码点,UTF-8 编码使用了 3 个字节(24 位),用二进制表示为 11100010 10011101 10100100(不带两个空白字符,每个字符使用 1 位,我添加它们只是为了视觉目的,为了使 24 位更具可读性,所以请忽略它们)。

\n

现在,我们的计算机如何知道这 3 个字节“11100010 10011101 10100100”是单独读取还是一起读取?如果这 3 个字节单独读取,然后转换为字符,结果将是“\xc3\x94,\xc3\x98,\xc3\xb1”,这与我们的心脏表情符号“\xe2\x9d\xa4”相比有很大不同”。

\n

2 - 编码标准(UTF-8、ISO-8859、Windows-1251 等)

\n

为了解决这个问题,人们发明了编码标准。\n自2008年以来,最流行的标准是UTF-8。UTF-8平均占所有网页的97.6%,这就是为什么我们将UTF-8,对于下面的例子。

\n

2.1 - 什么是编码?

\n

编码,简单地说就是将某种东西从一种东西转换成另一种东西。在我们的例子中,我们正在将数据(更具体地说是字节)转换为 UTF-8 格式,我还想将这句话重新表述为:“将字节转换为 UTF-8 字节”,尽管它在技术上可能不正确。

\n

2.2 有关 UTF-8 格式的一些信息以及它为何如此重要

\n

UTF-8 最少使用 1 个字节来存储一个字符,最多使用 4 个字节。由于 UTF-8 格式,我们可以使用占用超过 1 个字节信息的字符。

\n

这一点非常重要,因为如果没有 UTF-8 格式,我们就不可能拥有如此多样化的字母表,因为有些字母表的字母无法放入 1 个字节,我们也不会\根本没有表情符号,因为每个表情符号至少需要 3 个字节。我很确定您现在已经明白了要点,所以让我们继续前进。

\n

2.3 汉字编码为UTF-8示例

\n

现在,假设我们有汉字“\xe6\xb1\x89”。

\n

这个字符正好需要16个二进制位“01101100 01001001”,因此正如我们上面讨论的,我们无法读取这个字符,除非我们将其编码为UTF-8,因为计算机将无法知道这2个字节是否是单独或一起阅读。

\n

将这个“\xe6\xb1\x89”字符的 2 个字节转换为(我喜欢称之为 UTF-8)字节,将得到以下结果:

\n

(普通字节)“01101100 01001001” ->(UTF-8 编码字节)“11100110 10110001 10001001”

\n

现在,我们怎么会得到 3 个字节而不是 2 个字节呢?那怎么会是UTF-8编码,将2个字节变成3个字节呢?

\n

为了解释 UTF-8 编码是如何工作的,我将逐字复制 @MatthiasBraun 的回复,这是对他出色解释的大力赞扬。

\n

2.4 UTF-8编码实际上是如何工作的?

\n

我们这里有将字节编码为 UTF-8 的模板。这就是编码的发生方式,如果你问我的话,我会非常兴奋!

\n

现在,请仔细查看下表,然后我们将一起进行查看。

\n
        Binary format of bytes in sequence:\n\n        1st Byte    2nd Byte    3rd Byte    4th Byte    Number of Free Bits   Maximum Expressible Unicode Value\n        0xxxxxxx                                                7             007F hex (127)\n        110xxxxx    10xxxxxx                                (5+6)=11          07FF hex (2047)\n        1110xxxx    10xxxxxx    10xxxxxx                  (4+6+6)=16          FFFF hex (65535)\n        11110xxx    10xxxxxx    10xxxxxx    10xxxxxx    (3+6+6+6)=21          10FFFF hex (1,114,111)\n
Run Code Online (Sandbox Code Playgroud)\n
\n
    \n
  1. 上表中的“x”字符代表“Free\nBits”的数量,这些位是空的,我们可以写入它们。

    \n
  2. \n
  3. 其他位保留用于 UTF-8 格式,它们用作标头/标记。由于这些标头,当使用 UTF-8 编码读取字节时,计算机知道要一起读取哪些字节以及分别读取哪些字节。

    \n
  4. \n
  5. 使用 UTF-8 格式编码后,字符的字节大小取决于您需要写入的位数。

    \n
  6. \n
\n
    \n
  • 在我们的例子中,“\xe6\xb1\x89”字符恰好是 2 个字节或 16 位:

    \n
  • \n
  • “01101100 01001001”

    \n
  • \n
  • 因此,编码为 UTF-8 后字符的大小将是 3 个字节或 24 位

    \n
  • \n
  • “11100110 10110001 10001001”

    \n
  • \n
  • 因为“3 UTF-8 字节”有 16 个空闲位,我们可以写入

    \n
  • \n
\n
    \n
  1. 解决方案,分步如下:
  2. \n
\n
\n

2.5 解决方案:

\n
        Header  Place holder    Fill in our Binary   Result         \n        1110    xxxx            0110                 11100110\n        10      xxxxxx          110001               10110001\n        10      xxxxxx          001001               10001001 \n
Run Code Online (Sandbox Code Playgroud)\n

2.6 小结:

\n
        A Chinese character:      \xe6\xb1\x89\n        its Unicode value:        U+6C49\n        convert 6C49 to binary:   01101100 01001001\n        encode 6C49 as UTF-8:     11100110 10110001 10001001\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

UTF-8、UTF-16 和 UTF-32 编码之间差异的原始解释:https://javarevisited.blogspot.com/2015/02/difference- Between-utf-8-utf-16-and-utf。 html

\n

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

\n

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

\n

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

\n

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

\n

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

\n


wen*_*ang 16

1. Unicode

世界上有很多角色,比如"$,&,h,a,t,?,张,1,=,+ ......".

然后有一个致力于这些角色的组织,

他们制定了一个名为"Unicode"的标准.

标准如下:

  • 创建一个表单,其中每个位置称为"代码点"或"代码位置".
  • 整个位置从U + 0000到U + 10FFFF;
  • 到目前为止,一些位置充满了字符,其他位置被保存或为空.
  • 例如,位置"U + 0024"填充有字符"$".

PS:当然还有另一个名为ISO的组织维持另一个标准 - "ISO 10646",几乎相同.

2. UTF-8

如上所述,U + 0024只是一个位置,因此我们无法在计算机中为"$"保存"U + 0024".

必须有一种编码方法.

然后是编码方法,如UTF-8,UTF-16,UTF-32,UCS-2 ....

在UTF-8下,代码点"U + 0024"被编码为00100100.

00100100是我们在计算机中为"$"保存的值.

  • 一般来说,UTF-8 是当今人们使用的唯一变体。 (2认同)
  • ISO 10646 是与 Unicode 字符集相同的标准。Unicode 定义了很多字符集以外的东西,比如排序规则、大小写等。ISO 10646 只是字符集(目前有超过 130,000 个)。Unicode 联盟和 ISO 共同开发了 Unicode,其中 ISO 只关心字符集及其编码,而 Unicode 还定义了字符属性和处理文本的规则。 (2认同)

kom*_*mer 12

我已经检查了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?......"


Rai*_*rim 10

如果我可以总结一下我从这个线程中收集到的内容:

Unicode的“转化”字符序数(以十进制形式)

à -> 224
Run Code Online (Sandbox Code Playgroud)

UTF-8 是一种将这些序数(以十进制形式) “转换”为二进制表示的编码。

224 -> 11000011 10100000
Run Code Online (Sandbox Code Playgroud)

请注意,我们谈论的是 224的二进制表示,而不是它的二进制形式,即 0b11100000。


InG*_*eek 10

本文解释了所有细节 http://kunststube.net/encoding/

写入缓冲区

如果您写入 4 字节缓冲区,?使用 UTF8 编码的符号,您的二进制文件将如下所示:

00000000 11100011 10000001 10000010

如果您写入 4 字节缓冲区,?使用 UTF16 编码的符号,您的二进制文件将如下所示:

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.
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Dim*_*mos 5

它们是同一件事,不是吗?

不,他们不是。


我认为您引用的维基百科页面的第一句话给出了一个很好的简短摘要:

UTF-8 是一种可变宽度字符编码,能够使用一到四个 8 位字节对 Unicode 中的所有 1,112,064 个有效代码点进行编码。

详细说明:

  • Unicode是一个标准,它定义了从字符到数字的映射,即所谓的代码点(如下例所示)。对于完整的映射,您可以在这里查看。

    ! -> U+0021 (21),  
    " -> U+0022 (22),  
    \# -> U+0023 (23)
    
    Run Code Online (Sandbox Code Playgroud)
  • UTF-8 是以计算机可以理解的形式对这些代码点进行编码的方法之一,也称为。换句话说,它是一种将每个代码点转换为比特序列或将比特序列转换为等效代码点的方法/算法。请注意,Unicode 有很多替代编码。


乔尔在这里给出了非常好的解释和历史概述。