字符编码取决于代码点

时间:2017-08-24 18:23:31

标签: unicode character-encoding

有几种字符编码,似乎UTF-8处于领先地位,据说它是迄今为止效率最高的一种。所以我在想为什么我们不能用他们的代码点编码Unicode字符?

例如: 性格:'a','','Ј'...... 代码点:U + 0061,U + 00E2,U + 0408 ...... 编码字节:61,e2,408 ......

等等。这不是编码字符的最有效和最简单的方法吗?

1 个答案:

答案 0 :(得分:1)

单个8位字节最多可容纳256个值(0-255),因此无法按原样保存大部分Unicode代码点(超过100万)。

UTF(Unicode Transformation Formats)是标准化编码,旨在将Unicode代码点表示为编码代码单元,然后可以以字节格式表示。以UTF名称表示的数字表示用于编码每个代码单元的位数:

  • UTF-8使用8位codeunits
  • UTF-16使用16位codeunits
  • UTF-32使用32位codeunits
  • 等等(还有其他可用的UTF,但这3个是主要使用的。)

大多数UTF是可变长度的(UTF-32不是),需要一个或多个codeunits来编码给定的代码点:

  • 在UTF-8中,ASCII范围内的代码点(U + 0000 - U + 007F)使用1个代码单元,较高代码点使用2-4个代码单元,具体取决于代码点值。

  • 在UTF-16中,BMP(U + 0000 - U + FFFF)中的代码点使用1个代码单元,较高代码点使用2个代码单元(称为"代理对")。

  • 在UTF-32中,所有代码点都使用1个32位代码单元。

因此,例如,使用您提到的代码点,它们将按如下方式编码:

U+0061 LATIN SMALL LETTER A

UTF    | Codeunits | Bytes
-----------------------------------------
UTF-8  | x61       | x61
-----------------------------------------
UTF-16 | x0061     | x61 x00         (LE)
       |           | x00 x61         (BE)
-----------------------------------------
UTF-32 | x00000061 | x61 x00 x00 x00 (LE)
       |           | x00 x00 x00 x61 (BE)
U+00E2 SMALL LETTER A WITH CIRCUMFLEX

UTF    | Codeunits | Bytes
-----------------------------------------
UTF-8  | xC3 xA2   | xC3 xA2
-----------------------------------------
UTF-16 | x00E2     | xE2 x00         (LE)
       |           | x00 xE2         (BE)
-----------------------------------------
UTF-32 | x000000E2 | xE2 x00 x00 x00 (LE)
       |           | x00 x00 x00 xE2 (BE)
U+0408 CYRILLIC CAPITAL LETTER JE

UTF    | Codeunits | Bytes
-----------------------------------------
UTF-8  | xD0 x88   | xD0 x88
-----------------------------------------
UTF-16 | x0408     | x08 x04         (LE)
       |           | x04 x08         (BE)
-----------------------------------------
UTF-32 | x00000408 | x08 x04 x00 x00 (LE)
       |           | x00 x00 x04 x08 (BE)

只是为了好的衡量标准,以下是其他一些例子:

U+20AC EURO SIGN

UTF    | Codeunits   | Bytes
-------------------------------------------
UTF-8  | xE2 x82 xAC | xE2 x82 xAC
-------------------------------------------
UTF-16 | x20AC       | xAC x20         (LE)
       |             | x20 xAC         (BE)
-------------------------------------------
UTF-32 | x000020AC   | xAC x20 x00 x00 (LE)
       |             | x00 x00 x20 xAC (BE)
U+1F601 GRINNING FACE WITH SMILING EYES

UTF    | Codeunits       | Bytes
-----------------------------------------------
UTF-8  | xF0 x9F x98 x81 | xF0 x9F x98 x81
-----------------------------------------------
UTF-16 | xD83D xDE01     | x3D xD8 x01 xDE (LE)
       |                 | xD8 x3D xDE x01 (BE)
-----------------------------------------------
UTF-32 | x0001F601       | x01 xF6 x01 x00 (LE)
       |                 | x00 x01 xF6 x01 (BE)

正如您所看到的,就字节大小而言,UTF-8并不总是最有效的。它适用于基于拉丁语的语言,但对亚洲语言,符号,表情符号等不太好。另一方面,它不会受到像UTF-16和UTF-32这样的字节序问题的影响,所以它非常适合数据存储和通信。对于大多数 Unicode的常见用途,UTF-8足够好,但在某些情况下UTF-16更好。在处理内存中的Unicode数据时,UTF-16比UTF-8(UTF-32最好)更容易使用,因为处理的变化较少。