一个Unicode字符需要多less个字节?
我对编码有点困惑。 据我所知旧的ASCII字符每个字符一个字节。 Unicode字符需要多less个字节?
我假设一个Unicode字符可以包含来自任何语言的每个可能的字符 – 我是否正确? 那么每个字符需要多less字节?
而UTF-7,UTF-6,UTF-16等是什么意思? 他们是不同版本的Unicode?
我读了维基百科关于Unicode的文章,但对我来说很难。 我期待着看到一个简单的答案。
你不会看到一个简单的答案,因为没有一个。
首先,Unicode不包含“来自每种语言的每个字符”,尽pipe它确实尝试。
Unicode本身就是一个映射,它定义的码点和一个码点是一个数字, 通常与一个字符相关联。 通常我会说因为有字符组合等概念。 你可能熟悉口音或变音等。 这些可以用于另一个字符,如a
或u
来创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 encoding
。 UTF-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 + 0061拉丁小写字母A:
-
- U + 00A9版权标志:
©
- 编号:169
- UTF-8:C2 A9
- UTF-16:00 A9
- U + 00AE注册登记:
®
- 编号:174
- UTF-8:C2 AE
- UTF-16:00 AE
- U + 00A9版权标志:
-
- 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 + 1337 ETHIOPIC SYLLABLE PHWA:
-
- 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
- U + 1F4A9 POO OF:
好吧,我正在被带走…
有趣的事实:
- 如果你正在寻找一个特定的字符,你可以复制并粘贴在http://codepoints.net/ 。
- 我在这个无用的列表上浪费了很多时间(但它已经sorting了!)。
- MySQL有一个名为“utf8”的字符集,它实际上不支持长度超过3个字节的字符。 所以你不能插入一堆便便 ,领域将被悄悄截断。 改用“utf8mb4”。
- 有一个雪人testing页面(unicodesnowmanforyou.com) 。
在Unicode中,答案不容易给出。 正如你已经指出的那样,这个问题就是编码。
给定任何没有区别字符的英文句子,UTF-8的答案将是字符的字节数,而UTF-16的答案将是字符数乘以2。
唯一的编码(现在),我们可以做出关于大小的声明是UTF-32。 那里它总是每个字符32位,即使我想象的代码点为未来的UTF-64准备:)
是什么让这么难是至less有两件事:
- 组合的字符,而不是使用已经有重音/变音符号( – )的字符实体,用户决定合并重音和基本字符(`A)。
- 码点。 代码点是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代码单元”字段中。