我对编码有些困惑。据我所知,旧的ASCII字符每个字符占用一个字节。一个Unicode字符需要多少字节呢?
我认为一个Unicode字符可以包含任何语言中的所有可能字符 - 我是正确的吗?那么每个字符需要多少字节呢?
UTF-7、UTF-6、UTF-16等是什么意思?它们是不同版本的Unicode吗?
我看过维基百科关于Unicode的文章,但我觉得很难理解。期待能够得到简单明了的回答。
我对编码有些困惑。据我所知,旧的ASCII字符每个字符占用一个字节。一个Unicode字符需要多少字节呢?
我认为一个Unicode字符可以包含任何语言中的所有可能字符 - 我是正确的吗?那么每个字符需要多少字节呢?
UTF-7、UTF-6、UTF-16等是什么意思?它们是不同版本的Unicode吗?
我看过维基百科关于Unicode的文章,但我觉得很难理解。期待能够得到简单明了的回答。
令人惊讶的是,没有人指出如何计算一个 Unicode 字符占用多少字节。以下是 UTF-8 编码字符串的规则:
Binary Hex Comments
0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding
10xxxxxx 0x80..0xBF Continuation byte: one of 1-3 bytes following the first
110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding
1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding
11110xxx 0xF0..0xF7 First byte of a 4-byte character encoding
所以答案很简单:它需要1到4个字节,具体取决于第一个字节,该字节将指示它将占用多少个字节。
你想要得到的答案并不简单,因为它并不存在。
首先,Unicode 并不包含“每一种语言的每一个字符”,尽管它确实在努力尝试。
Unicode 本身是一种映射,它定义了码点,而码点是一个数字,通常与一个字符关联。我说“通常”是因为有像组合字符这样的概念。你可能熟悉像重音或分音符这样的东西。它们可以与另一个字符(如 a
或 u
)一起使用,从而创建一个新的逻辑字符。因此,一个字符可以由一个或多个码点组成。
为了在计算机系统中变得有用,我们需要选择一种表示这些信息的方式。这些就是各种 Unicode 编码,例如 utf-8、utf-16le、utf-32 等。它们主要通过其代码单元的大小来区分。UTF-32 是最简单的编码,它具有一个 32 位的代码单元,这意味着一个单独的码点可以轻松地放入代码单元中。其他编码将出现需要多个代码单元才能表示一个码点的情况,或者该特定码点根本无法在编码中表示(这是 UCS-2 中的问题)。
由于组合字符的灵活性,即使在给定的编码中,每个字符所占用的字节数也会因字符和规范化形式而异。这是处理具有多个表示形式的字符的一种协议(你可以说“带有重音符号的 ‘a’”,它由两个码点组成,其中一个是一个组合字符,或者 “带重音符号的‘a’”,它只有一个码点)。
虽然我知道这个问题很久了,并且已经有一个被接受的答案,但是我想提供一些例子(希望对某些人有用)。
据我所知,旧的ASCII字符每个字符占用一个字节。
没错。实际上,由于ASCII是7位编码,它支持128个代码(其中95个可打印),因此它只使用半个字节(如果这有任何意义的话)。
一个Unicode字符需要多少字节?
Unicode只是将字符映射到码点。它不定义如何对它们进行编码。文本文件中不包含Unicode字符,而是可能表示Unicode字符的字节/八位组。
我认为一个Unicode字符可以包含任何语言的所有可能字符 - 我是正确的吗?
不完全正确。但几乎是的。所以基本上是的。但仍然不完全正确。
那么每个字符需要多少字节?
与您的第二个问题相同。
UTF-7、UTF-6、UTF-16等是什么?它们是一些Unicode版本吗?
不,它们是编码。它们定义了如何使用字节/八位组表示Unicode字符。
以下是一些例子。如果有些例子无法在您的浏览器中显示(可能是因为字体不支持),请转到 http://codepoints.net/U+1F6AA
(将1F6AA
替换为十六进制代码点)以查看图像。
a
©
®
ጷ
—
‰
好的,我太沉迷于这个话题了...
有趣的事实:
简单来说,Unicode
是一个标准,它为世界上的所有字符(它仍在不断完善中)分配了一个数字(称为码点)。
现在您需要使用字节来表示这些码点,这就是所谓的字符编码
。 UTF-8,UTF-16,UTF-6
是表示这些字符的方式。
UTF-8
是一种多字节字符编码。字符可以有1到6个字节(其中一些可能现在不需要)。
UTF-32
每个字符都有4个字节。
UTF-16
每个字符使用16位,并且仅表示 Unicode 字符的一部分,称为 BMP (对于所有实际目的而言已足够)。Java 在其字符串中使用此编码。
1 byte: 0 - 7F (ASCII)
2 bytes: 80 - 7FF (all European plus some Middle Eastern)
3 bytes: 800 - FFFF (multilingual plane incl. the top 1792 and private-use)
4 bytes: 10000 - 10FFFF
2 bytes: 0 - D7FF (multilingual plane except the top 1792 and private-use)
4 bytes: D800 - 10FFFF
4 bytes: 0 - 10FFFF
U+20AC
)可以表示为三字节序列E2 82 AC
或四字节序列F0 82 82 AC
。Unicode
是一种标准,为每个字符提供唯一的编号。这些唯一的编号被称为码点
,适用于世界上存在的所有字符(有些还需要添加)。
出于不同的目的,您可能需要以字节表示这些码点
(大多数编程语言都这样做),这就是字符编码
的作用。
UTF-8
、UTF-16
、UTF-32
等都是字符编码
,Unicode的码点以不同的方式在这些编码中表示。
UTF-8
编码具有可变宽度长度,并且以其编码的字符可以占用1到4个字节。
对于UTF-16编码,如果字符以0xD800或更大的值开头,则需要四个字节(即两个代码单元)来表示该字符;这种字符被称为“代理对”(surrogate pair)。具体来说,代理对的格式如下:
[0xD800 - 0xDBFF] [0xDC00 - 0xDFF]
其中[...]表示具有给定范围的两个字节代码单元。任何小于等于0xD7FF的值都是一个代码单元(两个字节)。任何大于等于0xE000的值都是无效的(除了BOM标记,可以说)。
请参见http://unicodebook.readthedocs.io/unicode_encodings.html,第7.5节。