Unicode定義:
Unicode(統一碼、萬國碼、單一碼)是計算機科學領域里的一項業界標准,包括字符集、編碼方案等。Unicode 是為了解決傳統的字符編碼方案的局限而產生的,它為每種語言中的每個字符設定了統一並且唯一的二進制編碼,以滿足跨語言、跨平台進行文本轉換、處理的要求。
ASCll碼與Unicode編碼不同
對於很多初學者來說,特別容易將這兩個概念混淆,認為ASCLL碼就是Unicode編碼,這是明顯錯誤的。
我們知道:1個byte=8bit,1個bit=1位二進制數,一位二進制數又可以用0或者1來表示。所以一個字節能表示最大的數字就是256。計算機是美國人發明的,而英文中涉及的編碼並不多,一個字節可以表示所有字符了,所以ASCII(American national Standard Code for Information Interchange,美國國家標准信息交換碼)編碼就成為美國人的標准編碼。ASCLL碼雖然並須全面,但在所有字符集中,最知名的可能要數被稱為ASCII的8位字符集了。
Unicode編碼的由來:
我們都知道中文的字符肯定不止256個漢字,使用ASCII編碼來處理中文顯然是不夠的,所以中國制定了GB2312編碼,用兩個字節表示一個漢字,碰到及其特殊的情況,還會用三個字節來表示一個漢字。GB2312還把ASCII包含進去了。同理,日文,韓文等上百個國家為了解決這個問題發展了一套自己的編碼,於是乎標准越來越多,如果出現多種語言混合顯示就一定會出現亂碼。那么針對這種編碼“亂象”,Unicode便應運而生了,其將所有語言統一到一套編碼規則里。
Unicode編碼的問題:
ASCII編碼是1個字節,而Unicode編碼通常是2個字節。
字母A用ASCII編碼是十進制的65,二進制的01000001;
字符0用ASCII編碼是十進制的48,二進制的00110000,注意字符’0’和整數0是不同的;
漢字中已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
你可以猜測,如果把ASCII編碼的A用Unicode編碼,只需要在前面補0就可以,因此,A的Unicode編碼是00000000 01000001。
新的問題又出現了:如果統一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不划算。
正是由於這樣的原因,使得Unicode編碼一時間很難推廣,於是,為了較好的解決 Unicode 的編碼問題, UTF-8 和 UTF-16 應運而生。
UTF-8
UTF-8 是目前互聯網上使用最廣泛的一種 Unicode 編碼方式,它的最大特點就是可變長。它可以使用 1 - 4 個字節表示一個字符,根據字符的不同變換長度。UTF-8 的編碼規則很簡單,只有二條:
(1)對於單字節的符號,字節的第一位設為0,后面7位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
(2)對於需要使用 N 個字節來表示的字符(N > 1),第一個字節的前 N 位都設為 1,第 N + 1 位設為0,剩余的 N - 1 個字節的前兩位都設位 10,剩下的二進制位則使用這個字符的 Unicode 碼點來填充。
編碼規則如下
在這里插入圖片描述
UTF-16
在了解 UTF-16 編碼方式之前,先了解一下另外一個概念——“平面”。
在上面的介紹中,提到了 Unicode 是一本很厚的字典,她將全世界所有的字符定義在一個集合里。這么多的字符不是一次性定義的,而是分區定義。每個區可以存放 65536 個(2^16)字符,稱為一個平面(plane)。目前,一共有 17 個(2^5)平面,也就是說,整個 Unicode 字符集的大小現在是 2^21。
最前面的 65536 個字符位,稱為基本平面(簡稱 BMP ),它的碼點范圍是從 0 到 2^16-1,寫成 16 進制就是從 U+0000 到 U+FFFF。所有最常見的字符都放在這個平面,這是 Unicode 最先定義和公布的一個平面。剩下的字符都放在輔助平面(簡稱 SMP ),碼點范圍從 U+010000 到 U+10FFFF。
接下來我們再談UTF-16,UTF-16編碼采用了不同長度的編碼表示所有的Unicode碼點。在基本的多語言級別中,每個字符用16位表示,通常被稱為代碼單元;而輔助字符采用一對連續的代碼單元進行編碼。這樣構成的編碼值一定落入基本的多語言級別中空閑的2048字節內,通常被稱為替代區域(surrogate area)[U+D800–U+DBFF用於第一個代碼單元,U+DC00–U+DFFF用於第二個代碼單元]。這樣設計十分巧妙,我們可以迅速地知道一個代碼單元是一個字符的編碼,還是一個輔助字符的第一或第二部分。
在Java中,char類型用UTF-16編碼描述一個代碼單元。所以在Java編程中強烈建議不要使用char類型,除非確實需要對UTF-16代碼單元操作。最好將需要處理的字符串用抽象數據類型表示。
Unicode編碼與文字處理
在文字處理方面,Unicode為每一個字符而非字形定義唯一的代碼(即一個整數)。換句話說,統一碼以一種抽象的方式(即數字)來處理字符,並將視覺上的演繹工作(例如字體大小、外觀形狀、字體形態、文體等)留給其他軟件來處理,例如網頁瀏覽器或是文字處理器。