1、Unicode是什麼?
編碼
Unicode(統一碼、萬國碼、單一碼)是計算機科學領域裏的一項業界標準,包括字符集、編碼方案等。Unicode 是爲了解決傳統的字符編碼方案的侷限而產生的,它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言、跨平臺進行文本轉換、處理的要求。1990年開始研發,1994年正式公佈。spa
最先的字符編碼是ASCII碼,每一個字符是經過一個字節來表示的,可是隨着計算機的不斷髮展,許多文字並不能用一個字節來表示,爲了可以表示更多的語言文字,因此產生了Unicode,用兩個字節來對字符進行編碼,這樣的話像中文、日語等也可以成功的在計算機上顯示而且保存。在表示一個Unicode的字符時,一般會用「U+」而後緊接着一組十六進制的數字來表示這一個字符。code
2、UTF8/16/32分別是什麼?orm
1) UTF8:UTF-8以字節爲單位對Unicode進行編碼。從Unicode到UTF-8的編碼方式以下:blog
Unicode編碼(十六進制) 圖片 |
UTF-8 字節流(二進制)內存 |
000000-00007Funicode |
0xxxxxxxget |
000080-0007FFit |
110xxxxx 10xxxxxx |
000800-00FFFF |
1110xxxx 10xxxxxx 10xxxxxx |
010000-10FFFF |
11110xxx10xxxxxx10xxxxxx10xxxxxx |
UTF-8的特色:是對不一樣範圍的字符使用不一樣長度的編碼。對於0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼徹底相同。UTF-8編碼的最大長度是4個字節。從上表能夠看出,4字節模板有21個x,便可 以容納21位二進制數字。Unicode的最大碼位0x10FFFF也只有21位。
2)UTF16:UTF-16是Unicode字符編碼五層次模型的第三層:字符編碼表(Character Encoding Form,也稱爲 "storage format")的一種實現方式。即把Unicode字符集的抽象碼位映射爲16位長的 整數(即碼元)的序列,用於數據存儲或傳遞。Unicode字符的碼位,須要1個或者2個16位長的碼元來表示,所以這是一個變長表示。
3)UTF32:UTF-32 (或 UCS-4)是一種將Unicode字符編碼的協定,對每個Unicode碼位使用剛好32位元。其它的Unicode transformation formats則使用不定長度編碼。由於UTF-32對每一個字符都 使用4字節,就空間而言,是很是沒有效率的。特別地,非基本多文種平面的字符在大部分文件中一般很罕見,以至於它們一般被認爲不存在佔用空間大小的討論,使得UTF-32一般會是其它 編碼的二到四倍。雖然每個碼位使用固定長定的字節看似方便,它並不如其它Unicode編碼使用得普遍。
3、Unicode和UTF8/16/32之間的關係
首先要注意的是unicode是編碼字符集,而UTF-八、UTF-1六、UTF-32是字符集編碼。下面我來具體解釋一下:好比漢字的」漢」,在unicode中,漢」的unicode值爲0x6C49。問:把這個」漢」字保存到計算機中(硬盤、內存),機器碼是多少呢? 學過《計算機組成原理》的人都知道,計算機內部存儲的形式都是0101的二進制數字串。」漢」字保存在計算機裏確定也是0101的數字串。」漢」的unicode值是0x6C49,轉化爲2進制 1101100 01001001,那麼把這個」漢」字保存到計算機中也是 1101100 01001001 嗎?其實並非這樣的,答案取決於用到的字符集編碼是哪一種 好比你用到的字符集編碼是UTF-8,那麼」漢」字在計算機內部保存的值爲0xE6B189,也就是111001101011000110001001,能夠看到」漢」字變成了3個字節。UTF-8用1-4個字節來保存unicode編碼的字符。 而若是用UTF-16來保存,那麼」漢」字仍爲仍爲0x6C49,也就是 1101100 01001001。UTF-16只能是選兩字節或四字節來保存字符 而UTF-32就是把全部的字符都用32bit也就是4個字節來表示。 因此這就是編碼字符集和字符集編碼的區別。
UTF,即Unicode Transformer Format,是Unicode代碼點(code point)的實際表示方式,按其基本長度所用位數分爲UTF-8/16/32。它也能夠認爲是一種特殊的外部數據編碼,但可以與Unicode代碼點作一一對應。也就是其實從本質上說,UTF-八、UTF-1六、UTF-32 都是 Unicode 的一種實現,只是實現的方式不一樣罷了。因此UTF8/16/32是Unicode的衍生,和Unicode是息息相關的。接下來從這三個UTF開始分析和Unicode的關係。
一、UTF-32
這個就是字符所對應編號的整數二進制形式,四個字節。這個就是直接轉換。 好比馬的 Unicode 爲:U+9A6C,那麼直接轉化爲二進制,它的表示就爲:1001 1010 0110 1100。
這裏須要說明的是,轉換成二進制後計算機存儲的問題,咱們知道,計算機在存儲器中排列字節有兩種方式:大端法和小端法,大端法就是將高位字節放到低地址處,好比 0x1234, 計算機用兩個字節存儲,一個是高位字節 0x12,一個是低位字節 0x34,它的存儲方式爲下:
UTF-32 用四個字節表示,處理單元爲四個字節(一次拿到四個字節進行處理),若是不分大小端的話,那麼就會出現解讀錯誤,好比咱們一次要處理四個字節 12 34 56 78,這四個字節是表示 0x12 34 56 78 仍是表示 0x78 56 34 12?不一樣的解釋最終表示的值不同。
咱們能夠根據他們高低字節的存儲位置來判斷他們所表明的含義,因此在編碼方式中有 UTF-32BE 和 UTF-32LE,分別對應大端和小端,來正確地解釋多個字節(這裏是四個字節)的含義。
UTF-16 使用變長字節表示
① 對於編號在 U+0000 到 U+FFFF 的字符(經常使用字符集),直接用兩個字節表示。
② 編號在 U+10000 到 U+10FFFF 之間的字符,須要用四個字節表示。
一樣,UTF-16 也有字節的順序問題(大小端),因此就有 UTF-16BE 表示大端,UTF-16LE 表示小端。
UTF-8 就是使用變長字節表示,顧名思義,就是使用的字節數可變,這個變化是根據 Unicode 編號的大小有關,編號小的使用的字節就少,編號大的使用的字節就多。使用的字節個數從 1 到 4 個不等。
UTF-8 的編碼規則是:
① 對於單字節的符號,字節的第一位設爲 0,後面的7位爲這個符號的 Unicode 碼,所以對於英文字母,UTF-8 編碼和 ASCII 碼是相同的。
② 對於n字節的符號 (n>1),第一個字節的前 n 位都設爲 1,第 n+1 位設爲 0,後面字節的前兩位一概設爲 10,剩下的沒有說起的二進制位,所有爲這個符號的 Unicode 碼 。
舉個例子:好比說一個字符的 Unicode 編碼是 130,顯然按照 UTF-8 的規則一個字節是表示不了它(由於若是是一個字節的話前面的一位必須是 0),因此須要兩個字節(n = 2)。
根據規則,第一個字節的前 2 位都設爲 1,第 3(2+1) 位設爲 0,則第一個字節爲:110X XXXX,後面字節的前兩位一概設爲 10,後面只剩下一個字節,因此後面的字節爲:10XX XXXX。
因此它的格式爲 110XXXXX 10XXXXXX 。
下面咱們來具體看看具體的 Unicode 編號範圍與對應的 UTF-8 二進制格式
那麼對於一個具體的 Unicode 編號,具體怎麼進行 UTF-8 的編碼呢?
首先找到該 Unicode 編號所在的編號範圍,進而能夠找到與之對應的二進制格式,而後將該 Unicode 編號轉化爲二進制數(去掉高位的 0),最後將該二進制數從右向左依次填入二進制格式的 X 中,若是還有 X 未填,則設爲 0 。
好比:「馬」的 Unicode 編號是:0x9A6C,整數編號是 39532,對應第三個範圍(2048 - 65535),其格式爲:1110XXXX 10XXXXXX 10XXXXXX,39532 對應的二進制是 1001 1010 0110 1100,將二進制填入進去就爲:
11101001 10101001 10101100 。
因爲 UTF-8 的處理單元爲一個字節(也就是一次處理一個字節),因此處理器在處理的時候就不須要考慮這一個字節的存儲是在高位仍是在低位,直接拿到這個字節進行處理就好了,由於大小端是針對大於一個字節的數的存儲問題而言的。
從上面的講解也能看出來,UTF8/16/32都是Unicode的一種實現方式。