Unicode代碼點與編碼方式

一、Unicode字符集

  UTF編碼,全稱是Unicode Transformer Format,這種編碼是UCS(Universal Mutiple-Octet Doded Character Set,國際標準ISO10646規定的通用字符集)的實際形式,它的分類是按照其基本長度所佔用的位數而定,分為UTF-8/16/32三種形式。UTF可以說是其他字符集的集合,它使得其它字符集是交叉兼容的,可以說,凡是將文字元號轉為UCS後再轉回原來的編碼,也不會丟失信息。UCS包含了現在所有的已知語言的字元,包含從拉丁文、希臘語到中文、韓文等象形文字,再到日文的平假名、片假名等眾多語系 。因此使用UTF進行程序開發,絕對是程序國際化的首選,Unicode將世界的語言統一起來,構成了最偉大的字符集。

二、代碼點與代碼單元

  代碼點和代碼單元,是從Unicode標準而來的術語,Unicode標準的核心是一個編碼字符集。

  代碼點 Code Point:與一個Unicode編碼表中的某個字元對應的代碼值。

  代碼單元 Code Unit:一個Java中的char,可以理解為字元編碼的一個基本單元。

三、編碼方式

  Unicode編碼空間從U+000000到U+10FFFF,Unicode4.0將字元分配給這1112064個代碼點中的96382個代碼點。

  Unicode的編碼空間劃為17個平面,每個平面包含216(65536)個碼位。17個平面碼位可表示為「U+xx0000」到「U+xxFFFF」(xx表示十六進位從0x00到0x10,共計17個平面)。

  從U+000000至U+00FFFF之間的字元稱為基本多文種平面(BMP)。這是16位編碼的原始標準,早期由於錯誤地估算了代碼點的容量範圍,認為Unicode最多只需要2^16個代碼點。

  其他平面為輔助平面,也就是代碼點在U+10000至U+10FFFF範圍之間的字元,又稱為增補字元,也就是那些使用原始的Unicode的16位設計無法表示的字元。

四、Unicode在Java中的表示

  Java中用char來表示Unicode字元,由於剛開始Unicode最多使用16bit表示。因此char能夠表示全部的Unicode字元。後來由於Unicode4.0規定Unicode支持的字元遠遠超過65536個字元。因此char現在不能表示所有的unicode字元。僅僅能表示0x000000到0x00FFFF之間的字元。也就是說,char不能表示增補字元。

  Java中用int表示所有Unicode代碼點。int的21個低位(最低有效位)用於表示Unicode代碼點,並且11個高位(最高有效位)必須為零。也就是說,int能表示出char不能表示的增補字元。

五、UTF-8、UTF-16、UTF-32

  UTF,是Unicode代碼點的實際表示方式,按其基本長度所用位數分為UTF-8/16/32。它也可以認為是一種特殊的外部數據編碼,但能夠與Unicode代碼點做一一對應。

  UTF-8是變長編碼,每個Unicode代碼點按照不同範圍,可以有1-3位元組的不同長度。是壓縮的Unicode編碼方式.

  UTF-16長度相對固定,只要不處理大於U200000範圍的字元,每個Unicode代碼點使用16位即2位元組表示,超出部分使用兩個UTF-16即4位元組表示。按照高低位位元組順序,又分為UTF-16BE/UTF-16LE。

  UTF-32長度始終固定,每個Unicode代碼點使用32位即4位元組表示。按照高低位位元組順序,又分為UTF-32BE/UTF-32LE。

  UTF編碼有個優點,即儘管編碼位元組數不等,但是不像gb2312/gbk編碼一樣,需要從文本開始尋找,才能正確對漢字進行定位。在UTF編碼下,根據相對固定的演算法,從當前位置就能夠知道當前位元組是否是一個代碼點的開始還是結束,從而相對簡單的進行字元定位。不過定位問題最簡單的還是UTF- 32,它根本不需要進行字元定位,但是相對的大小也增加不少。

  UTF-32 即將每一個 Unicode 代碼點表示為相同值的 32 位整數。很明顯,它是內部處理最方便的表達方式,但是,如果作為一般字元串表達方式,則要消耗更多的內存。

  UTF-16 使用一個或兩個未分配的 16 位代碼單元的序列對 Unicode 代碼點進行編碼。值 U+0000 至U+FFFF 編碼為一個相同值的 16位單元。增補字元編碼為兩個代碼單元,第一個單元來自於高代理範圍(U+D800 至U+DBFF),第二個單元來自於低代理範圍(U+DC00至 U+DFFF)。這在概念上可能看起來類似於多位元組編碼,但是其中有一個重要區別:值U+D800 至 U+DFFF 保留用於 UTF-16;沒有這些值分配字元作為代碼點。這意味著,對於一個字元串中的每個單獨的代碼單元,軟體可以識別是否該代碼單元表示某個單單元字元,或者是否該代碼單元是某個雙單元字元的第一個或第二單元。這相當於某些傳統的多位元組字元編碼來說是一個顯著的改進,在傳統的多位元組字元編碼中,位元組值 0x41 既可能表示字母「A」,也可能是一個雙位元組字元的第二個位元組。

  UTF-8 使用一至四個位元組的序列對編碼 Unicode 代碼點進行編碼。U+0000 至U+007F 使用一個位元組編碼,U+0080至 U+07FF 使用兩個位元組,U+0800 至 U+FFFF使用三個位元組,而U+10000 至 U+10FFFF 使用四個位元組。UTF-8 設計原理為:位元組值 0x00 至0x7F 始終表示代碼點U+0000 至 U+007F(Basic Latin 字元子集,它對應 ASCII 字符集)。這些位元組值永遠不會表示其他代碼點,這一特性使 UTF-8 可以很方便地在軟體中將特殊的含義賦予某些 ASCII 字元。

  下表所示為幾個字元不同表達方式的比較:

Unicode 代碼點

U+0041

U+00DF

U+6771

U+10400

表示字形

A

(char無法識別)

UTF-32 代碼單元

00000041

000000DF

00006771

00010400

UTF-16 代碼單元

0041

00DF

6771

D801

DC00

UTF-8 代碼單元

41

C3

9F

E6

9D

B1

F0

90

90

80

推薦閱讀:

iOS KVO crash 自修復技術實現與原理解析
業力與大腦神經編碼記憶 腦可塑性-大腦皮層增大-記憶學習經歷固化 大腦重構 關鍵期MeCP2蛋白 中風大腦修復
應該學習編碼的5個理由
你好,類型(二):Lambda calculus

TAG:代碼 | 方式 | 編碼 |