一个Unicode字符占用多少字节?

nan*_*nan 224 language-agnostic string unicode encoding

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

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

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

我阅读了有关Unicode维基百科文章,但这对我来说非常困难.我期待看到一个简单的答案.

pau*_*ago 182

奇怪的是,没有人指出如何计算一个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
Run Code Online (Sandbox Code Playgroud)

所以快速回答是:它需要1到4个字节,具体取决于第一个字节,它将指示它将占用多少字节.

更新

正如prewett所指出的,此规则仅适用于UTF-8

  • 我相信4字节字符的最大十六进制值是0xF7(而不是0xF4). (7认同)
  • 0xF4 不是一个错误,而是一个澄清。Unicode 代码点的范围是 0-0x10ffff,因此最后一个代码点编码为 F4 8F BF BF。 (2认同)

Log*_*ldo 136

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

首先,Unicode不包含"来自每种语言的每个字符",尽管它肯定会尝试.

Unicode本身是一个映射,它定义了代码点,而代码点是一个数字,通常与一个字符相关联.我说通常是因为有像组合字符这样的概念.你可能熟悉口音或变音符号之类的东西.这些可以与另一个角色一起使用,例如a a或a u来创建新的逻辑角色.因此,字符可以包含1个或多个代码点.

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

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


bas*_*ic6 36

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

据我所知,旧的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 UMBRELLA与雨水滴: ?
      • 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黑色标志: ?
      • Nº:9873
      • UTF-8:E2 9A 91
      • UTF-16:26 91
    • U + 269B ATOM符号: ?
      • 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邮戳面: ?
      • 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 OF 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

好的,我被带走了......

有趣的事实:

  • 更正:1)ASCII是7位,一个字节是8位,所以它远远超过一半.2)Unicode确实定义了如何编码代码点.UTF-8,UTF-16和UTF-32在Unicode标准中定义. (5认同)
  • @JonathanRosenne我认为他/他表示仅使用8位表示的可能值的一半,而不是使用一半的位。 (3认同)
  • 我真的很喜欢这些例子。他们强调了例如为什么人们可能更喜欢UTF-16而不是UTF-8。不同软件的开发人员可以根据更有可能使用Unicode字符来选择不同的编码。例如,在中国/日本,UTF-16(2个字节)比UTF-8更有意义,因为相同的字符通常需要两倍的字节才能在UTF-8中进行编码 (2认同)

Zim*_*bao 28

简单来说,它Unicode是一个为世界上所有角色分配一个数字(称为代码点)的标准(它仍在进行中).

现在,您需要使用字节来表示此代码点,即调用它们character encoding.UTF-8, UTF-16, UTF-6是表示这些角色的方式.

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

UTF-32 每个字符有4个字节的字符.

UTF-16每个字符使用16位,它只代表称为BMP的Unicode字符的一部分(出于所有实际目的,它足够了).Java在其字符串中使用此编码.

  • Unicode是一个21位代码集,4个字节足以表示UTF-8中的任何Unicode字符.UTF-16使用代理来表示BMP之外的字符(基本多语言平面); 它需要2或4个字节来表示任何有效的Unicode字符.UCS-2是UTF-16的16位变体,不支持BMP之外的代理或字符. (9认同)
  • 这个答案指出UTF-16不能编码BMP代码点.这是不正确的,因为这些可以使用代理对在UTF-8中进行编码.(在Unicode 2.0问世之前,你必须考虑过时的UCS-2,它只编码16位代码点.)另外,Java并不完全使用UTF-16,它使用了修改后的形式,其中代码点0的编码方式不同. (3认同)
  • 我输错了; 我原本打算说"非BMP".答案中的错误是它表示UTF-16代表BMP字符,这是不准确的.UTF-16可以编码所有unicode字符 - 非BMP字符通过代理对编码.也许回答者与UCS-2混淆了. (3认同)

Joh*_*ohn 13

在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
Run Code Online (Sandbox Code Playgroud)

在UTF-16中:

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

在UTF-32中:

4 bytes:      0 - 10FFFF
Run Code Online (Sandbox Code Playgroud)

根据定义,10FFFF是最后一个unicode代码点,它的定义是因为它是UTF-16的技术限制.

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


0xC*_*22L 8

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

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

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

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

  1. 组合字符,用户决定组合重音符号和基本字符(`A),而不是使用已经加音/变音符号(À)的字符实体.
  2. 代码点.代码点是UTF编码允许编码的方法,而不是为其提供名称通常允许的位数.例如,UTF-8指定某些字节,这些字节本身是无效的,但是当跟随有效的连续字节时,将允许描述超出8位范围0..255的字符.请参阅维基百科关于UTF-8的文章中的示例和超长编码.
    • 给出的优秀示例是€字符(代码点U+20AC可以表示为三字节序列E2 82 AC四字节序列F0 82 82 AC.
    • 两者都是有效的,这表明在讨论"Unicode"时答案是多么复杂,而不是关于Unicode的特定编码,例如UTF-8或UTF-16.


Nic*_*ell 7

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

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


Lod*_*ijk 5

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

正如此引用所表明的,您的问题是您假设 Unicode 是编码字符的单一方式。实际上,Unicode 有多种形式,并且,再次引用该内容,其中一种甚至每个字符有 1 个字节,就像您习惯的那样。

所以你想要的简单答案是它会有所不同。