2017-08-24 48 views
0

有幾種字符編碼,看起來像UTF-8是領先的,據說它是目前爲止效率最高的一種。所以我在想,爲什麼我們不能用他們的代碼點來編碼Unicode字符呢?取決於代碼點的字符編碼

例如: 性格: 'A', 'A', 'Ј' ... 代碼點:U + 0061,U + 00E2,U + 0408 ... 編碼的字節:61,E2, 408 ...

等等。這不是編碼字符最有效和最簡單的方法嗎?

+2

'0x408'不適合字節。 – PetSerAl

+0

正如@PetSerAl指出的那樣,這不是一種編碼。當你需要表示U + 0408時,它將佔用多個字節。 UTF-8,UTF-16和UTF-32是使用多個字節編碼該信息的不同方式。他們有不同的權衡。 – janm

+0

UTF-8對文件和流很常見。自從VB4,Java,.NET,JavaScript,Win32 API等以來,UTF-16(或其前身UCS-2)已用於內存中文本處理。 –

回答

1

一個8位字節最多可以保存256個值(0-255),因此它不能保存大部分Unicode代碼點(超過100萬)。

UTF(Unicode Transformation Formats)是標準化的編碼,旨在將Unicode代碼點表示爲編碼的代碼單元,然後可以用字節格式表示。在一個UTF的名稱所表示的數字表示比特的用於將每個codeunit編碼#:

  • UTF-8採用8位CODEUNITS
  • UTF-16使用16位CODEUNITS
  • UTF-32使用32位CODEUNITS
  • 等等(還有其他的UTF可用,但這3個是主要使用的)。

大多數因此UTF是可變長度(UTF-32是不),需要1個或多個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這樣的endian問題的影響,所以它是非常適合數據存儲和通信。對於大多數 Unicode的常見用途,UTF-8足夠體面,儘管在某些情況下UTF-16更好。在處理內存中的Unicode數據時,UTF-16比UTF-8(UTF-32最好)更容易處理,因爲處理的變體較少。

+0

沒有人提到過密碼單元,但現在很明顯。謝謝 :) –