我对编码有点困惑。据我所知,旧的 ASCII 字符每个字符占用一个字节。一个 Unicode 字符需要多少字节?
我假设一个 Unicode 字符可以包含来自任何语言的所有可能字符 - 我正确吗?那么每个字符需要多少字节呢?
UTF-7、UTF-6、UTF-16 等是什么意思?它们是不同版本的 Unicode 吗?
我阅读了Wikipedia article about 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
)一起使用以创建新的逻辑字符。因此,一个字符可以包含 1 个或多个代码点。
为了在计算系统中有用,我们需要为这些信息选择一个表示。这些是各种 unicode 编码,例如 utf-8、utf-16le、utf-32 等。它们的区别主要在于其代码单元的大小。 UTF-32 是最简单的编码,它有一个 32 位的代码单元,这意味着一个单独的代码点可以轻松地融入一个代码单元。其他编码会出现一个代码点需要多个代码单元的情况,或者该特定代码点根本无法在编码中表示(这是 UCS-2 的一个问题)。
由于组合字符的灵活性,即使在给定的编码中,每个字符的字节数也会根据字符和规范化形式而有所不同。这是一种用于处理具有多个表示形式的字符的协议(您可以说 "an 'a' with an accent"
是 2 个代码点,其中一个是组合字符或 "accented '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
替换为十六进制代码点)查看图像。
U+0061 拉丁小写字母 A:a Nº:97 UTF-8:61 UTF-16:00 61 U+00A9 版权符号:© Nº:169 UTF-8:C2 A9 UTF-16:00 A9 U+00AE 注册符号: ® Nº: 174 UTF-8: C2 AE UTF-16: 00 AE U+1337 ETHIOPIC SYLLABLE PHWA:ጷ Nº: 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 PER MILLE SIGN: ‰ Nº: 8240 UTF-8: E2 80 B0 UTF-16: 20 30 U+20AC EURO SIGN: € Nº: 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:☃ Nº:9731 UTF-8:E2 98 83 UTF-16:26 03 U+260E 黑色电话:☎ Nº:9742 UTF-8:E2 98 8E UTF-16:26 0E U+2614 雨伞:☔ Nº:9748 UTF-8:E2 98 94 UTF -16:26 14 U+263A 白色笑脸:☺ Nº:9786 UTF-8:E2 98 BA UTF-16:26 3A U+2691 BLACK FLAG:⚑ Nº:9873 UTF-8:E2 9A 91 UTF-16: 26 91 U+269B 原子符号:⚛ Nº:9883 UTF-8:E2 9A 9B UTF-16:26 9B U+2708 飞机:✈ Nº: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 POSTAL MARK FACE: 〠 Nº: 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: 💩 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/ 上复制并粘贴它。
我在这个无用的列表上浪费了很多时间(但它已经排序了!)。
MySQL 有一个名为“utf8”的字符集,它实际上不支持超过 3 个字节的字符。所以不能插入一堆便便,字段会被默默截断。请改用“utf8mb4”。
有一个雪人测试页面 (unicodesnowmanforyou.com)。
00A9
而不是 00 A9
(这将是 UTF-16BE)。
简单地说 Unicode
是一种标准,它为世界上的所有字符分配一个数字(称为代码点)(它仍在进行中)。
现在您需要使用字节来表示此代码点,即 character encoding
。 UTF-8, UTF-16, UTF-6
是表示这些字符的方式。
UTF-8
是多字节字符编码。字符可以有 1 到 6 个字节(其中一些现在可能不需要)。
UTF-32
每个字符有 4 个字节一个字符。
UTF-16
为每个字符使用 16 位,它仅代表称为 BMP 的 Unicode 字符的一部分(对于所有实际目的来说,它就足够了)。 Java 在其字符串中使用这种编码。
在 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 的一半。
在 Unicode 中,答案并不容易给出。正如您已经指出的那样,问题在于编码。
给定任何没有变音符号的英文句子,UTF-8 的答案将是与字符一样多的字节,而对于 UTF-16,它将是字符数乘以 2。
(截至目前)我们可以声明大小的唯一编码是 UTF-32。每个字符总是 32 位,尽管我认为代码点是为未来的 UTF-64 准备的 :)
导致它如此困难的原因至少有两点:
组合字符,而不是使用已经重音/变音符号 (À) 的字符实体,用户决定将重音符号和基本字符 (`A) 结合起来。码点。代码点是 UTF-encodings 允许编码的位数超过其名称通常允许的位数的方法。例如,UTF-8 指定了某些本身无效的字节,但是当后面跟着一个有效的连续字节时,将允许描述一个超出 0..255 的 8 位范围的字符。请参阅下面有关 UTF-8 的 Wikipedia 文章中的示例和超长编码。给出的一个很好的例子是 € 字符(代码点 U+20AC 可以表示为三字节序列 E2 82 AC 或四字节序列 F0 82 82 AC。两者都是有效的,这表明答案是多么复杂当谈论“Unicode”而不是 Unicode 的特定编码时,例如 UTF-8 或 UTF-16。
有一个很棒的工具可以计算 UTF-8 中任何字符串的字节数:http://mothereff.in/byte-counter
更新:@mathias 已公开代码:https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js
好吧,我也刚刚打开了 Wikipedia 页面,在介绍部分我看到“Unicode 可以通过不同的字符编码来实现。最常用的编码是 UTF-8(它对任何 ASCII 字符使用一个字节,它有“
正如这句话所表明的那样,您的问题是您假设 Unicode 是编码字符的单一方式。实际上有多种形式的 Unicode,同样在那个引用中,其中一种甚至每个字符有 1 个字节,就像你习惯的那样。
因此,您想要的简单答案是它会有所不同。
Unicode
是一个 standard,它为每个字符提供一个唯一编号。对于世界上存在的所有字符,这些唯一的数字被称为 code point
(这只是唯一的代码)(一些仍有待添加)。
出于不同的目的,您可能需要以字节表示此 code points
(大多数编程语言都这样做),这就是 Character Encoding
的作用所在。
UTF-8
、UTF-16
、UTF-32
等都是 Character Encodings
,而 Unicode 的代码点在这些编码中以不同的方式表示。
UTF-8
编码具有可变宽度长度,其中编码的字符可以占用 1 到 4 个字节(含);
UTF-16
具有可变长度,其中编码的字符可以占用 1 或 2 个字节(即 8 位或 16 位)。这仅代表称为 BMP(基本多语言平面)的所有 Unicode 字符的一部分,几乎适用于所有情况。 Java 对其字符串和字符使用 UTF-16
编码;
UTF-32
具有固定长度,每个字符正好占用 4 个字节(32 位)。
对于 UTF-16,如果字符以 0xD800 或更大开头,则需要四个字节(两个代码单元);这样的字符称为“代理对”。更具体地说,代理对具有以下形式:
[0xD800 - 0xDBFF] [0xDC00 - 0xDFF]
其中 [...] 表示具有给定范围的两字节代码单元。任何 <= 0xD7FF 都是一个代码单元(两个字节)。任何 >= 0xE000 都是无效的(可以说除了 BOM 标记)。
请参阅 http://unicodebook.readthedocs.io/unicode_encodings.html,第 7.5 节。
看看这个Unicode code converter。例如,在“0x...表示法”字段中输入 0x2009
,其中 2009 is the Unicode number for thin space,然后单击转换。十六进制数 E2 80 89
(3 个字节)出现在“UTF-8 代码单元”字段中。
来自维基:
UTF-8,一种 8 位可变宽度编码,可最大限度地与 ASCII 兼容; UTF-16,一种 16 位的可变宽度编码; UTF-32,一种 32 位、固定宽度的编码。
这是三种最流行的不同编码。
在 UTF-8 中,每个字符都被编码为 1 到 4 个字节(主要编码)
在 UTF16 中,每个字符被编码为 1 到 2 个 16 位字,并且
在 UTF-32 中,每个字符都被编码为单个 32 位字。
不定期副业成功案例分享