我对编码有点困惑。据我所知,旧的ASCII字符每个字符占用一个字节。Unicode字符需要多少个字节?
我假设一个Unicode字符可以包含任何语言的所有可能字符-我正确吗?那么每个字符需要多少个字节?
UTF-7,UTF-6,UTF-16等是什么意思?它们是Unicode的不同版本吗?
我阅读了有关Unicode的Wikipedia文章,但对我来说却很难。我期待看到一个简单的答案。
我对编码有点困惑。据我所知,旧的ASCII字符每个字符占用一个字节。Unicode字符需要多少个字节?
我假设一个Unicode字符可以包含任何语言的所有可能字符-我正确吗?那么每个字符需要多少个字节?
UTF-7,UTF-6,UTF-16等是什么意思?它们是Unicode的不同版本吗?
我阅读了有关Unicode的Wikipedia文章,但对我来说却很难。我期待看到一个简单的答案。
Answers:
您不会看到一个简单的答案,因为没有答案。
首先,尽管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'"
哪个是一个代码点)。
奇怪的是,没有人指出如何计算占用一个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个字节,具体取决于第一个字节,这将表明它将占用多少字节。
我知道这个问题很旧,并且已经有一个可以接受的答案,但是我想提供一些示例(希望它对某人有用)。
据我所知,旧的ASCII字符每个字符占用一个字节。
对。实际上,由于ASCII是7位编码,因此它支持128个代码(其中95个是可打印的),因此它仅使用半个字节(如果有意义)。
Unicode字符需要多少个字节?
Unicode只是将字符映射到代码点。它没有定义如何编码它们。文本文件不包含Unicode字符,但是可以表示Unicode字符的字节/八位字节。
我假设一个Unicode字符可以包含任何语言的所有可能字符-我正确吗?
不,但是差不多。所以基本上是。但是仍然没有。
那么每个字符需要多少个字节?
与您的第二个问题相同。
UTF-7,UTF-6,UTF-16等是什么意思?它们是某种Unicode版本吗?
不,这些是编码。它们定义字节/八位字节应如何表示Unicode字符。
几个例子。如果其中一些不能在您的浏览器中显示(可能是因为字体不支持它们),请转到http://codepoints.net/U+1F6AA
(用1F6AA
十六进制的代码点替换)查看图像。
a
©
®
ጷ
—
‰
€
™
☃
☎
☔
☺
⚑
⚛
✈
✞
〠
肉
💩
🚀
好吧,我被带走了...
有趣的事实:
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。即使我认为代码点已为将来的UTF-64做好了准备,每个字符总是有32位:)
使其如此困难的原因至少有两点:
U+20AC
可以表示为三字节序列E2 82 AC
或四字节序列F0 82 82 AC
。有一个很棒的工具可以计算UTF-8中任何字符串的字节:http : //mothereff.in/byte-counter
更新:@mathias已公开代码:https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js
对于UTF-16,如果字符以0xD800或更大的字符开头,则需要四个字节(两个代码单元);这样的字符称为“代理对”。更具体地说,代理对具有以下形式:
[0xD800 - 0xDBFF] [0xDC00 - 0xDFF]
[...]表示具有给定范围的两字节代码单元。<= 0xD7FF的任何内容都是一个代码单位(两个字节)。> = 0xE000的任何内容都是无效的(可以说BOM表标记除外)。
请参阅http://unicodebook.readthedocs.io/unicode_encodings.html,第7.5节。
查看此Unicode代码转换器。例如,在“ 0x ...表示法”字段中输入0x2009
,其中2009是瘦空间的Unicode编号,然后单击转换。十六进制数E2 80 89
(3个字节)出现在“ UTF-8代码单位”字段中。
Unicode
是为每个字符提供唯一编号的标准。这些唯一的数字称为code point
s(这是唯一的代码),用于世界上所有存在的字符(有些字符仍要添加)。
出于不同的目的,您可能需要code points
用字节表示(大多数编程语言都用字节表示),这就是Character Encoding
开始的地方。
UTF-8
,UTF-16
,UTF-32
等都是Character Encodings
和Unicode代码点在这些编码来表示,以不同的方式。
UTF-8
编码具有可变宽度的长度,并且其中编码的字符可以占用1-4个字节(包括1和4个字节);
UTF-16
具有可变长度,并且其中编码的字符可以占用1或2个字节(8或16位)。这仅表示称为BMP(基本多语言平面)的所有Unicode字符的一部分,几乎可以满足所有情况。Java使用UTF-16
字符串和字符编码。
UTF-32
具有固定长度,每个字符正好占用4个字节(32位)。