一个Unicode字符需要多少字节?

我对编码有点困惑。据我所知,旧的ASCII字符每个字符占用一个字节。一个Unicode字符需要多少字节?

我假设一个Unicode字符可以包含任何语言的所有可能字符——我说的对吗?那么每个字符需要多少字节呢?

UTF-7、UTF-6、UTF-16等是什么意思?它们是Unicode的不同版本吗?

我读了关于Unicode的维基百科文章,但对我来说太难了。我期待看到一个简单的答案。

363732 次浏览

好吧,我刚刚也打开了维基百科的页面,在介绍部分我看到“Unicode可以通过不同的字符编码实现。最常用的编码是UTF-8(它对任何ASCII字符使用一个字节,这些字符在UTF-8和ASCII编码中具有相同的编码值,对其他字符使用最多四个字节),现在已经过时的UCS-2(它对每个字符使用两个字节,但不能对当前Unicode标准中的每个字符进行编码)。

正如这段引用所演示的,您的问题是假定Unicode是一种编码字符的单一方法。实际上有多种形式的Unicode,在引用中,其中一种甚至每个字符有一个字节,就像你习惯的那样。

所以你想要的简单答案是它是变化的。

在Unicode中,答案是不容易给出的。正如您已经指出的,问题在于编码。

对于任何没有变音符字符的英语句子,UTF-8的答案将是字符的字节数,而UTF-16的答案将是字符数乘以2。

(到目前为止)我们可以声明大小的唯一编码是UTF-32。每个字符总是32位,即使我想象代码点是为未来的UTF-64准备的:)

至少有两件事让它如此困难:

  1. 组合字符,用户决定将重音字符和基本字符(' a)结合起来,而不是使用已经有重音/变音符的字符实体(À)。
  2. <李>代码点。代码点是一种方法,通过这种方法,utf -编码允许编码超过其名称通常允许的比特数。例如,UTF-8指定某些字节本身是无效的,但当后面跟着一个有效的延续字节时,将允许描述超出0..255 8位范围的字符。参见下面关于UTF-8的维基百科文章中的例子太长的编码
    • 这里给出的一个很好的例子是,字符(代码点U+20AC)可以表示为三个字节序列E2 82 AC4字节序列F0 82 82 AC
    • 严格地说,正如在评论中指出的那样,这似乎不再是这种情况,甚至是基于我的误解。引用更新后的维基百科文章如下: 较长的编码称为过长,并且不是编码点的有效UTF-8表示形式。

简单地说,Unicode是一个将一个数字(称为码位)分配给世界上所有字符的标准(它仍在进行中)。

现在你需要使用字节来表示这些代码点,这被称为character encodingUTF-8, UTF-16, UTF-6是表示这些字符的方法。

UTF-8是多字节字符编码。字符可以有1到6个字节(其中一些现在可能不需要)。

UTF-32每个字符有4个字节一个字符。

UTF-16为每个字符使用16位,它只表示称为BMP的Unicode字符的一部分(对于所有实际目的来说已经足够了)。Java在其字符串中使用这种编码。

你不会看到一个简单的答案,因为根本就没有答案。

首先,Unicode并没有包含“每一种语言的每一个字符”,尽管它确实尝试了。

Unicode本身是一个映射,它定义码点,码点是一个数字,与通常字符相关联。我说通常是因为有像组合字符这样的概念。你可能对口音或变音很熟悉。它们可以与另一个字符一起使用,例如au来创建一个新的逻辑字符。因此,一个字符可以由一个或多个码位组成。

为了在计算系统中有用,我们需要为这些信息选择一种表示方式。这些是各种unicode编码,比如utf-8, utf-16le, utf-32等等。它们的区别主要在于代码单元的大小。UTF-32是最简单的编码,它有一个32位的代码单元,这意味着一个单独的代码点可以很好地适应一个代码单元。其他编码会出现这样的情况:一个代码点需要多个代码单元,或者这个特定的代码点根本不能在编码中表示(这就是UCS-2的一个问题)。

由于组合字符的灵活性,即使在给定的编码中,每个字符的字节数也可以根据字符和规范化形式而变化。这是一个用于处理具有多个表示形式的字符的协议(你可以说"an 'a' with an accent"是2个码点,其中一个是组合字符或"accented 'a'"是一个码点)。

有一个很棒的工具可以计算UTF-8中任意字符串的字节数:http://mothereff.in/byte-counter

更新:@mathias已将代码公开:https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js

看看这个Unicode码转换器。例如,输入0x2009,其中2009是窄空间的Unicode数字在“0x…”字段,然后单击Convert。十六进制数E2 80 89(3字节)出现在“UTF-8 code units”字段中。

我知道这个问题已经很老了,并且已经有了一个公认的答案,但我想提供一些例子(希望对某人有用)。

据我所知,旧的ASCII字符每个字符占用一个字节。

正确的。实际上,由于ASCII是一种7位编码,它支持128个代码(其中95个是可打印的),所以它只使用半个字节(如果有意义的话)。

一个Unicode字符需要多少字节?

Unicode只是将字符映射到码点。它没有定义如何编码它们。文本文件不包含Unicode字符,但可能包含表示Unicode字符的字节/八字节。

我假设一个Unicode字符可以包含所有可能 任何语言的字符,我说的对吗?< / p >

不。但几乎。所以基本上是的。但还是没有。

那么每个字符需要多少字节呢?

第二个问题同。

UTF-7、UTF-6、UTF-16等是什么意思?它们是统一码吗 版本?< / p >

不,那些是编码。它们定义字节/八字节应该如何表示Unicode字符。

举几个例子。如果其中一些无法在浏览器中显示(可能是因为字体不支持),则转到http://codepoints.net/U+1F6AA(将1F6AA替换为十六进制代码点)来查看图像。

    <李> < ul >
  1. U+0061拉丁小字母A: a
    • Nº:97
    • utf - 8: 61
    • Utf-16: 00 61
    • 李< / ul > < / > 李< / ul > < / > <李> < ul >
    • U+00A9版权标识:©
      • Nº:169
      • Utf-8: c2 a9
      • Utf-16: 00 a9
      • 李< / ul > < / >
      • U+00AE注册号:®
        • Nº:174
        • Utf-8: c2 ae
        • Utf-16: 00 ae
        • 李< / ul > < / > 李< / ul > < / > <李> < ul >
        • U+1337埃塞俄比亚音节PHWA:
          • Nº:4919
          • Utf-8: e1 8c b7
          • Utf-16: 13 37
          • 李< / ul > < / >
          • U+2014 EM DASH:
            • Nº:8212
            • Utf-8: e2 80 94
            • Utf-16: 20
            • 李< / ul > < / >
            • U+2030每英里符号:
              • Nº:8240
              • Utf-8: e2 80 b0
              • Utf-16: 20 30
              • 李< / ul > < / >
              • U+20AC欧元符号:
                • Nº:8364
                • Utf-8: e2 82 ac
                • Utf-16: 20 ac
                • 李< / ul > < / >
                • U+2122商标标志:
                  • Nº:8482
                  • Utf-8: e2 84 a2
                  • Utf-16: 21 22
                  • 李< / ul > < / > 雪人:
                    • Nº:9731
                    • Utf-8: e2 98 83
                    • Utf-16: 26 03
                    • 李< / ul > < / >
                    • U+260E黑色电话:
                      • Nº:9742
                      • Utf-8: e2 98 8e
                      • Utf-16: 26 0e
                      • 李< / ul > < / >
                      • U+2614带雨滴的雨伞:
                        • Nº:9748
                        • Utf-8: e2 98 94
                        • Utf-16: 26 14
                        • 李< / ul > < / >
                        • U+263A白色笑脸:
                          • Nº:9786
                          • Utf-8: e2 98 ba
                          • Utf-16: 26 3a
                          • 李< / ul > < / >
                          • U+2691 BLACK FLAG:
                            • Nº:9873
                            • Utf-8: e2 9a 91
                            • Utf-16: 26 91
                            • 李< / ul > < / >
                            • U+269B原子符号:
                              • Nº:9883
                              • Utf-8: e2 9a 9b
                              • Utf-16: 26 9b
                              • 李< / ul > < / >
                              • U+2708飞机:
                                • Nº:9992
                                • Utf-8: e2 9c 88
                                • Utf-16: 27 08
                                • 李< / ul > < / > U+271E阴影白色拉丁十字:
                                  • Nº:10014
                                  • Utf-8: e2 9c 9e
                                  • Utf-16: 27 1e
                                  • 李< / ul > < / >
                                  • U+3020邮政标志面:
                                    • Nº:12320
                                    • Utf-8: e3 80 a0
                                    • Utf-16: 30 20
                                    • 李< / ul > < / >
                                    • U+8089 CJK统一表意文字-8089:
                                      • Nº:32905
                                      • Utf-8: e8 82 89
                                      • Utf-16: 80 89
                                      • 李< / ul > < / > 李< / ul > < / > <李> < ul > 一堆屎:💩
                                        • Nº:128169
                                        • Utf-8: f0 9f 92 a9
                                        • Utf-16: d8 3d dc a9
                                        • 李< / ul > < / >
                                        • U+1F680 ROCKET: 🚀
                                          • Nº:128640
                                          • Utf-8: f0 9f 9a 80
                                          • Utf-16: d8 3d de 80
                                          • 李< / ul > < / > 李< / ul > < / >

好吧,我有点忘乎所以了……

有趣的事实:

奇怪的是,没有人指出如何计算一个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个字节,这取决于第一个将表明它将占用多少字节。

对于UTF-16,如果字符以0xD800或更大开头,则需要四个字节(两个代码单元);这样的字符称为“代理对”。更具体地说,代理对的形式是:

[0xD800 - 0xDBFF]  [0xDC00 - 0xDFF]

在[…]表示给定范围的双字节代码单元。任何<= 0xD7FF都是一个代码单元(两个字节)。任何>= 0xE000都是无效的(BOM标记除外)。

参见http://unicodebook.readthedocs.io/unicode_encodings.html,第7.5节。

在utf - 8:

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

在utf - 16:

2 bytes:      0 -   D7FF     (multilingual plane except the top 1792 and private-use )
4 bytes:   D800 - 10FFFF

在utf - 32:

4 bytes:      0 - 10FFFF

根据定义,10FFFF是最后一个unicode码位,这样定义是因为它是UTF-16的技术限制。

它也是UTF-8可以在4字节内编码的最大码点,但UTF-8编码背后的思想也适用于5字节和6字节编码,以覆盖码点,直到7FFFFFFF。只有UTF-32的一半。

从维基:

UTF-8, 8位可变宽度编码,最大限度地兼容ASCII;

UTF-16,一种16位变宽编码;

UTF-32, 32位,固定宽度编码。

这是三种最流行的不同编码。

  • 在UTF-8中,每个字符被编码成1到4个字节(主要编码)
  • 在UTF16中,每个字符被编码成1到2个16位的单词和
  • 在UTF-32中,每个字符都被编码为一个32位的单词。

Unicode是一个标准,它为每个字符提供了一个唯一的数字。这些唯一的数字被称为code points(这只是唯一的代码),适用于世界上所有存在的字符(一些字符仍有待添加)。

出于不同的目的,你可能需要用字节来表示这个code points(大多数编程语言都这样做),这里就是Character Encoding发挥作用的地方。

UTF-8UTF-16UTF-32等等都是Character Encodings, Unicode的码位在这些编码中以不同的方式表示。

< p > < br > UTF-8编码具有可变宽度长度,其中编码的字符可以占用1到4个字节(包括)

UTF-16具有可变长度,其中编码的字符可以占用1或2字节(即8或16位)。这只代表了称为BMP(基本多语言平面)的所有Unicode字符的一部分,对于几乎所有的情况都足够了。Java对其字符串和字符使用UTF-16编码;

UTF-32有固定的长度,每个字符恰好占用4个字节(32位)。