首先,說一說Unicode字符集。計算機內存中數據都是01這樣的二進制形式,可是對於人來講直接使用這樣的二進制是很是不方便的。咱們使用的是咱們熟悉的字符例如’A’,’一’這樣的字符。因此咱們須要轉換一下,這種轉換是須要一種對照(映射)關係吧?字符集就能夠看作是一種映射表。ASCII,GBK,Unicode字符集均可以看作是映射表。node
當咱們經過鍵盤(或其餘輸入設備),輸入字符時,輸入設備(或者響應的系統或者驅動)就會對其編碼。例如咱們使用ASCII編碼當咱們輸入字符’A’的時候就會被編碼爲0x41(A的十六進制)存入內存中,計算機要作屏幕(或其餘輸出設備)上顯示字符A就把0x41經過相應的驅動程序輸出到屏幕,屏幕控制相應的設備(例如電子槍)打出A字符。編輯器
知道了大體的過程,咱們接下來就來介紹一些Unicode字符集。由於每個地方使用的字符時不同的例如美國是用’a’這樣的字符,中國使用’一’這樣的字符,字符不同,字符集固然也不同。因此美國ASCII編碼,中使用GBK,GB18030這樣的編碼。這樣不一致,不說不能交流,可是交流確定是不方便的。因此出來了一個Unicode組織,制定了一個Unicode字符集,基本能夠照顧到各個國家的感覺,你們都能使用它知足基本要求,這樣有了共同語言(相同字符集)就好交流了。編碼
Unicode字符集使用4字節的數字來表達每一個字母、符號,或者表意文字。Unicode只是字符集,至於怎樣對他進行編碼,最經常使用的有3中方式,UTF-32編碼方式,這種簡單粗暴,直接使用4個字節(32位,Unicode字符集就是4個字節)來編碼,因此也沒有什麼技巧和特殊處理,不用計算和檢查什麼。spa
另一種是UTF-16,這種編碼方式是使用2個字節(16位)來編碼Unicode字符集。想想啊,用2個字節來存放4個字節的東西,確定須要一些特殊的技巧。UTF-16使用以下的表示方式:code
若是字符編碼U小於65535,則直接使用兩字節表示;內存
若是字符編碼U大於65536,因爲UNICODE編碼範圍最大爲1114111,從65536到1114111之間 共有1048575((2^20)-1)個編碼,也就是須要20個bit就能夠標示這些編碼。用U'表示從1048575之間的值,將其前 10 bit做爲高位和數值0xD800(16位)進行 邏輯or 操做,將後10 bit做爲低位和0xDC00(16位)作邏輯or 操做,這樣組成的 4個byte就構成了U的編碼。it
採用UTF-16這樣的編碼方式,空間效率顯然獲得了提高。可是人的創造力仍是值得驚歎的,一些聰明的傢伙又想出了UTF-8編碼的方式,UTF-8是一種變長編碼方式。它能夠只使用1-6個字節來編碼一個Unicode字符。Unicode字符才4個字節,UTF-8有多是有6個字節,這樣作真的有效率。事實上用5,6個字節來編碼的仍是不多的,UTF-8因此空間效率仍是很好的,否則也不會被普遍使用。UTF-8的編碼方式以下:字符編碼
若是一個字符用一個字節編碼,則最高位是0,其餘位給出編碼值(0到127);效率
若是一個字符用n(n>=2)個字節編碼,則第一個字節的前n位爲1,接着是一個0。隨後的(n-1)個字節所有由「10」開頭。全部字節的剩餘位鏈接起來,造成了Unicode代碼點值。因而可知:技巧
(1)一個以0開頭的字節表示單字節字符
(2)一個以11開頭的字節表示一個多字節字符的開頭
(3)一個以10開頭的字節表示一個多字節字符的非開頭
這樣說可能有一點空洞,咱們來一個實際的例子來看一看:
在Java中咱們常用\u4E00-\u9FA5這樣的方式來匹配中文漢字。由於Java使用的是Unicode字符集。\u4E00-\u9FA5這個範圍就是Unicode字符集中的基本漢字的範圍。下面咱們以第一個漢字的Unicode字符\u4E00來介紹一下UTF-8怎樣對Unicode字符編碼。基本漢字在Unicode使用2有效的字節,因此UTF-8對基本漢字使用3個字節對其進行編碼。
首先:把\u4E00轉換成二進制:0100111000000000(注意不滿16位高位補0)
按UTF-8的編碼規則,3個字節的樣式應該是:
111xxxxx
10xxxxxx
10xxxxxx
如今的問題關鍵是到底怎樣填呢?從Unicode的低位開始按6爲分開(由於如是多字節,除開第一個字節其餘的都差6位),最高字節不知高位補0。
上面的\u4E00就被拆成了:
0100 111000 000000
咱們先看高位0100只有4位和高字節的111組合只有7爲還差一位,怎麼辦?高位補0,因而就變爲11100100,其餘2個字節也同樣,因此最後變爲下面的3個字節:
11100100 10111000 10000000(十六進制E4 B8 80)
你能夠在編輯器中輸入一個字符’一’,保存爲UTF-8的格式。而後使用十六進制查看器打開,看到它的十六進制的編碼爲E4 B8 80,固然也多是EF BB BF E4 B8 80這其中的EF BB BF是UTF-8的BOM(字節順序標記(Byte Order Mark)。在Windows中的記事本會自動加上這3個字節。其餘有些編輯器也能夠指定加不加這3個字節,例如nodepad++就能夠指定編碼爲以UTF-8無BOM的格式編碼。