根据维基百科UTF-8页面,我从人们那里听到了相互矛盾的观点。

它们是一样的,不是吗?有人能澄清一下吗?


当前回答

不幸的是,“Unicode”根据上下文以各种不同的方式使用。它最正确的用法(IMO)是作为编码字符集——即一组字符以及字符与表示它们的整数码位之间的映射。

UTF-8是一种字符编码——一种将字节序列转换为字符序列的方法,反之亦然。它涵盖了整个Unicode字符集。ASCII编码为每个字符一个字节,其他字符根据其确切的码位占用更多字节(当前定义的所有码位最多4个字节,即最多U-0010FFFF,实际上4个字节可以处理最多U-001FFFFF)。

当“Unicode”被用作字符编码的名称时(例如,作为. net编码。Unicode属性)通常表示UTF-16,它将大多数常见字符编码为两个字节。一些平台(特别是。net和Java)使用UTF-16作为它们的“原生”字符编码。如果您需要担心不能在单个UTF-16值中编码的字符(它们被编码为“代理对”),这将导致一些棘手的问题——但大多数开发人员从不担心这一点,IME。

关于Unicode的一些参考:

Unicode联盟网站,特别是教程部分 乔尔的文章 我自己的文章(面向. net)

其他回答

作为一个直截了当的简单回答:

Unicode是一种表示多种人类语言字符的标准。 UTF-8是一种编码Unicode字符的方法。


是的:我故意忽略了UTF-8的内部工作原理。

UTF-8是一种使用8位序列编码Unicode字符的方法。

Unicode是一种用于表示来自多种语言的各种字符的标准。

在阅读了大量关于这个话题的帖子和文章后,我的解释是:

1 - Unicode字符表

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

在这1114112个码点中,有11111998个可以存储Unicode字符, 因为有2048个码点保留为代理,66个码点保留为非字符。 所以,有1,111,998个码位可以存储唯一的字符、符号、表情符号等。

然而,到目前为止,在这1114112个代码点中,只有144697个被使用。 这144,697个代码点包含了涵盖所有语言的字符,以及符号、表情符号等。

Each character in the "Unicode" is assigned to a specific codepoint aka has a specific value / Unicode number. For Example the character "❤", has the following value aka Unicode number "U+2764". The value "U+2764" takes exactly one codepoint out of the 1,114,112 codepoints. The value "U+2764" looks like that in binary: "11100010 10011101 10100100", which is exactly 3 bytes or 24bits (without the two empty space characters, each of which taking 1 bit, but I have added them for visual purposes only, in order to make the 24bits more readable, so please ignore them).

现在,我们的计算机应该如何知道这3个字节“11100010 10011101 10100100”是分开读还是一起读?如果将这3个字节分别读取,然后转换为字符,结果将是“Ô, Ø, ñ”,这与我们的心形表情符号“❤”有很大的不同。

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

为了解决这个问题,人们发明了编码标准。 自2008年以来,最流行的是UTF-8。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"

现在,我们是如何得到3个字节而不是2个字节的呢?这怎么可能是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)

The "x" characters in the table above represent the number of "Free Bits", those bits are empty and we can write to them. The other bits are reserved for the UTF-8 format, they are used as headers / markers. Thanks to these headers, when the bytes are being read using the UTF-8 encoding, the computer knows, which bytes to read together and which seperately. The byte size of your character, after being encoded using the UTF-8 format, depends on how many bits you need to write. In our case the "汉" character is exactly 2 bytes or 16bits: "01101100 01001001" thus the size of our character after being encoded to UTF-8, will be 3 bytes or 24bits "11100110 10110001 10001001" because "3 UTF-8 bytes" have 16 Free Bits, which we can write to Solution, step by step below:

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编码之间差异的原始解释: https://javarevisited.blogspot.com/2015/02/difference-between-utf-8-utf-16-and-utf.html

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位。

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

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

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

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

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

这是一个排序的列表,其中有一些随机的例子。