我对编码有点困惑。据我所知,旧的ASCII字符每个字符占用一个字节。一个Unicode字符需要多少字节?
我假设一个Unicode字符可以包含任何语言的所有可能字符——我说的对吗?那么每个字符需要多少字节呢?
UTF-7、UTF-6、UTF-16等是什么意思?它们是Unicode的不同版本吗?
我读了维基百科上关于统一码的文章,但对我来说太难了。我期待看到一个简单的答案。
我对编码有点困惑。据我所知,旧的ASCII字符每个字符占用一个字节。一个Unicode字符需要多少字节?
我假设一个Unicode字符可以包含任何语言的所有可能字符——我说的对吗?那么每个字符需要多少字节呢?
UTF-7、UTF-6、UTF-16等是什么意思?它们是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可以通过不同的字符编码实现。最常用的编码是UTF-8(它对任何ASCII字符使用一个字节,这些字符在UTF-8和ASCII编码中具有相同的编码值,对其他字符使用最多四个字节),现在已经过时的UCS-2(它对每个字符使用两个字节,但不能对当前Unicode标准中的每个字符进行编码)。
正如这段引用所演示的,您的问题是假定Unicode是一种编码字符的单一方法。实际上有多种形式的Unicode,在引用中,其中一种甚至每个字符有一个字节,就像你习惯的那样。
所以你想要的简单答案是它是变化的。
Unicode是一种为每个字符提供唯一编号的标准。这些唯一的数字被称为代码点(这只是唯一的代码),适用于世界上所有存在的字符(有些字符还有待添加)。
出于不同的目的,您可能需要用字节表示这些代码点(大多数编程语言都是这样做的),这就是字符编码发挥作用的地方。
UTF-8、UTF-16、UTF-32等等都是字符编码,Unicode的码位以不同的方式在这些编码中表示。
UTF-8编码具有可变宽度长度,其中编码的字符可以占用1到4个字节(包括);
UTF-16具有可变长度,其中编码的字符可以占用1或2个字节(即8或16位)。这只代表了称为BMP(基本多语言平面)的所有Unicode字符的一部分,对于几乎所有的情况都足够了。Java对其字符串和字符使用UTF-16编码;
UTF-32有固定的长度,每个字符正好占用4个字节(32位)。
奇怪的是,没有人指出如何计算一个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中,答案是不容易给出的。正如您已经指出的,问题在于编码。
对于任何没有变音符字符的英语句子,UTF-8的答案将是字符的字节数,而UTF-16的答案将是字符数乘以2。
(到目前为止)我们可以声明大小的唯一编码是UTF-32。每个字符总是32位,即使我想象代码点是为未来的UTF-64准备的:)
至少有两件事让它如此困难:
composed characters, where instead of using the character entity that is already accented/diacritic (À), a user decided to combine the accent and the base character (`A). code points. Code points are the method by which the UTF-encodings allow to encode more than the number of bits that gives them their name would usually allow. E.g. UTF-8 designates certain bytes which on their own are invalid, but when followed by a valid continuation byte will allow to describe a character beyond the 8-bit range of 0..255. See the Examples and Overlong Encodings below in the Wikipedia article on UTF-8. The excellent example given there is that the € character (code point U+20AC can be represented either as three-byte sequence E2 82 AC or four-byte sequence F0 82 82 AC. Both are valid, and this shows how complicated the answer is when talking about "Unicode" and not about a specific encoding of Unicode, such as UTF-8 or UTF-16. Strictly speaking, as pointed out in a comment, this doesn't seem to be the case any longer or was even based on a misunderstanding on my part. The quote from the updated Wikipedia article reads: Longer encodings are called overlong and are not valid UTF-8 representations of the code point.
对于UTF-16,如果字符以0xD800或更大开头,则需要四个字节(两个代码单元);这样的字符称为“代理对”。更具体地说,代理对的形式是:
[0xD800 - 0xDBFF] [0xDC00 - 0xDFF]
在[…]表示给定范围的双字节代码单元。任何<= 0xD7FF的值都是一个代码单元(两个字节)。任何>= 0xE000都是无效的(BOM标记除外)。
参见http://unicodebook.readthedocs.io/unicode_encodings.html,第7.5节。