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

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

我假设一个Unicode字符可以包含来自任何语言的每个可能的字符 – 我是否正确? 那么每个字符需要多less字节?

而UTF-7,UTF-6,UTF-16等是什么意思? 他们是不同版本的Unicode?

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

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

首先,Unicode不包含“来自每种语言的每个字符”,尽pipe它确实尝试。

Unicode本身就是一个映射,它定义的码点和一个码点是一个数字, 通常与一个字符相关联。 通常我会说因为有字符组合等概念。 你可能熟悉口音或变音等。 这些可以用于另一个字符,如au来创build一个新的逻辑字符。 一个字符因此可以由一个或多个码点组成。

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

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

奇怪的是,没有人指出如何计算一个Unicode字符的字节数。 这是UTF-8编码string的规则:

 Binary Hex Comments 0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding 10xxxxxx 0x80..0xBF Continuation bytes (1-3 continuation bytes) 110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding 1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding 11110xxx 0xF0..0xF4 First byte of a 4-byte character encoding 

所以快速的答案是:它需要1到4个字节,这取决于第一个字节,它将表明将占用多less字节。

更新

正如prewett指出的,这个规则只适用于UTF-8

简单地说, Unicode是一个为世界上的所有angular色分配了一个数字(称为代码点)的标准(它仍在工作中)。

现在你需要用字节表示这个代码点,这就是所谓的character encodingUTF-8, UTF-16, UTF-6是表示这些字符的方法。

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

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

UTF-16对每个字符使用16位,它只表示一部分被称为BMP的Unicode字符(为了所有的实际目的,它就足够了)。 Java在其string中使用此编码。

我知道这个问题很老,已经有了一个可以接受的答案,但是我想提供一些例子(希望对某人有用)。

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

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

Unicode字符需要多less个字节?

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

我假设一个Unicode字符可以包含来自任何语言的每个可能的字符 – 我是否正确?

不,但几乎。 所以基本上是的。 但仍然没有。

那么每个字符需要多less字节?

和你的第二个问题一样。

而UTF-7,UTF-6,UTF-16等是什么意思? 他们是一些types的Unicode版本?

不,这些是编码。 他们定义了字节/八位字节应该如何表示Unicode字符。

几个例子。 如果其中一些无法在浏览器中显示(可能是因为字体不支持),请转至http://codepoints.net/U+1F6AA (用hex代码replace1F6AA )以查看图像。

    • U + 0061拉丁小写字母A: a
      • 97号
      • UTF-8:61
      • UTF-16:00 61
    • U + 00A9版权标志: ©
      • 编号:169
      • UTF-8:C2 A9
      • UTF-16:00 A9
    • U + 00AE注册登记: ®
      • 编号:174
      • UTF-8:C2 AE
      • UTF-16:00 AE
    • U + 1337 ETHIOPIC SYLLABLE PHWA:
      • 编号:4919
      • UTF-8:E1 8C B7
      • UTF-16:13 37
    • U + 2014 EM DASH:
      • Nº:8212
      • UTF-8:E2 80 94
      • UTF-16:20 14
    • U + 2030年每英里标志:
      • 编号:8240
      • UTF-8:E2 80 B0
      • UTF-16:20 30
    • U + 20AC EURO SIGN:
      • 编号:8364
      • UTF-8:E2 82 AC
      • UTF-16:20 AC
    • U + 2122商标注册:
      • Nº:8482
      • UTF-8:E2 84 A2
      • UTF-16:21 22
    • U + 2603 SNOWMAN:
      • 9731
      • UTF-8:E2 98 83
      • UTF-16:26 03
    • U + 260E黑电话:
      • 编号:9742
      • UTF-8:E2 98 8E
      • UTF-16:26 0E
    • U + 2614
      • 编号:9748
      • UTF-8:E2 98 94
      • UTF-16:26 14
    • U + 263A白色笑脸:
      • 编号:9786
      • UTF-8:E2 98 BA
      • UTF-16:26 3A
    • U + 2691 BLACK FLAG:
      • 9873
      • UTF-8:E2 9A 91
      • UTF-16:26 91
    • U + 269B ATOM符号:
      • 编号:9883
      • UTF-8:E2 9A 9B
      • UTF-16:26 9B
    • U + 2708 AIRPLANE:
      • 编号:9992
      • UTF-8:E2 9C 88
      • UTF-16:27 08
    • U + 271E阴影白色拉丁十字架:✞
      • Nº:10014
      • UTF-8:E2 9C 9E
      • UTF-16:27 1E
    • U + 3020 MARK FACE:
      • 编号:12320
      • UTF-8:E3 80 A0
      • UTF-16:30 20
    • U + 8089 CJK UNIFIED IDEOGRAPH-8089:
      • Nº:32905
      • UTF-8:E8 82 89
      • UTF-16:80 89
    • U + 1F4A9 POO OF: 💩
      • Nº:128169
      • UTF-8:F0 9F 92 A9
      • UTF-16:D8 3D DC A9
    • U + 1F680 ROCKET: 🚀
      • Nº:128640
      • UTF-8:F0 9F 9A 80
      • UTF-16:D8 3D DE 80

好吧,我正在被带走…

有趣的事实:

  • 如果你正在寻找一个特定的字符,你可以复制并粘贴在http://codepoints.net/
  • 我在这个无用的列表上浪费了很多时间(但它已经sorting了!)。
  • MySQL有一个名为“utf8”的字符集,它实际上不支持长度超过3个字节的字符。 所以你不能插入一堆便便 ,领域将被悄悄截断。 改用“utf8mb4”。
  • 有一个雪人testing页面(unicodesnowmanforyou.com) 。

在Unicode中,答案不容易给出。 正如你已经指出的那样,这个问题就是编码。

给定任何没有区别字符的英文句子,UTF-8的答案将是字符的字节数,而UTF-16的答案将是字符数乘以2。

唯一的编码(现在),我们可以做出关于大小的声明是UTF-32。 那里它总是每个字符32位,即使我想象的代码点为未来的UTF-64准备:)

是什么让这么难是至less有两件事:

  1. 组合的字符,而不是使用已经有重音/变音符号( – )的字符实体,用户决定合并重音和基本字符(`A)。
  2. 码点。 代码点是UTF编码允许编码的方法,它比通常允许的位数多。 例如,UTF-8指定某些字节本身是无效的,但后跟一个有效的连续字节将允许描述超过0..255的8位范围的字符。 请参阅维基百科关于UTF-8的文章中的示例和Overlong编码。
    • 这里给出的一个很好的例子就是€字符(代码点U+20AC可以表示为三字节序列E2 82 AC或者四字节序列F0 82 82 AC
    • 两者都是有效的,这说明在讨论“Unicode”时的答案有多复杂,而不是关于Unicode的特定编码,如UTF-8或UTF-16。

有一个很好的工具来计算UTF-8中任何string的字节: http : //mothereff.in/byte-counter

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

在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-16,如果字符以0xD800或更大开始,则需要四个字节(两个代码单元); 这样的angular色被称为“代理对”。 更具体地说,代理对的forms是:

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

其中[…]表示具有给定范围的双字节代码单元。 任何<= 0xD7FF是一个代码单元(两个字节)。 任何> = 0xE000都是无效的(除了BOM标记,可以说)。

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

那么我也只是把维基百科的页面拉上去了,在介绍部分我看到“Unicode可以用不同的字符编码实现,最常用的编码是UTF-8(任何ASCII字符都使用一个字节,在UTF-8和ASCII编码中使用相同的代码值,对于其他字符使用最多4个字节),现在已经过时的UCS-2(每个字符使用两个字节,但不能编码当前Unicode标准中的每个字符)“

正如这句话所示,你的问题是,你认为Unicode是一种编码字符的单一方式。 实际上有多种forms的Unicode,而且在那个引用中,其中一个甚至每个字符有1个字节,就像你习惯的那样。

所以你想要的简单答案是不一样的。

我知道这只是一个链接,但你应该看看这个。

http://farmdev.com/talks/unicode/

它解释了python如何处理unicode,同时提供了对ASCII和UNICODE的清晰简洁的解释。

这就是我开始理解编码的一般方法。

看看这个Unicode代码转换器 。 例如,在“0x … notation”字段中input0x2009 ,其中2009是精简空格的Unicode编号 ,然后单击Convert。 hex数字E2 80 89 (3字节)出现在“UTF-8代码单元”字段中。