Unicode

Unicode的來歷

提到編碼,首先要說的是ASCII碼

ASCII碼

在學校學 C 語言的時候学密,了解到一些計算機內(nèi)部的機制淘衙,知道所有的信息最終都表示為一個二進制的字符串,每一個二進制位有 0 和 1 兩種狀態(tài)腻暮,通過不同的排列組合彤守,使用 0 和 1 就可以表示世界上所有的東西,感覺有點中國“太極”的感覺——“太極生兩儀哭靖,兩儀生四象具垫,四象生八卦”。

在計算機種中试幽,1 字節(jié)對應 8 位二進制數(shù)筝蚕,而每位二進制數(shù)有 0、1 兩種狀態(tài)抡草,因此 1 字節(jié)可以組合出 256 種狀態(tài)饰及。如果這 256 中狀態(tài)每一個都對應一個符號,就能通過 1 字節(jié)的數(shù)據(jù)表示 256 個字符康震。美國人于是就制定了一套編碼(其實就是個字典)燎含,描述英語中的字符和這 8 位二進制數(shù)的對應關系,這被稱為 ASCII 碼腿短。

ASCII 碼一共定義了 128 個字符屏箍,例如大寫的字母 A 是 65(這是十進制數(shù),對應二進制是0100 0001)橘忱。這 128 個字符只使用了 8 位二進制數(shù)中的后面 7 位赴魁,最前面的一位統(tǒng)一規(guī)定為 0。

歷史問題

英語用 128 個字符來編碼完全是足夠的钝诚,但是用來表示其他語言颖御,128 個字符是遠遠不夠的。于是凝颇,一些歐洲的國家就決定潘拱,將 ASCII 碼中閑置的最高位利用起來疹鳄,這樣一來就能表示 256 個字符。但是芦岂,這里又有了一個問題瘪弓,那就是不同的國家的字符集可能不同,就算它們都能用 256 個字符表示全禽最,但是同一個碼
點(也就是 8 位二進制數(shù))表示的字符可能可能不同腺怯。例如,144 在阿拉伯人的 ASCII 碼中是 ?川无,而在俄羅斯的 ASCII 碼中是 ?呛占。

因此,ASCII 碼的問題在于盡管所有人都在 0 - 127 號字符上達成了一致舀透,但對于 128 - 255 號字符上卻有很多種不同的解釋栓票。與此同時,亞洲語言有更多的字符需要被存儲愕够,一個字節(jié)已經(jīng)不夠用了走贪。于是,人們開始使用兩個字節(jié)來存儲字符惑芭。

各種各樣的編碼方式成了系統(tǒng)開發(fā)者的噩夢坠狡,因為他們想把軟件賣到國外。于是遂跟,他們提出了一個“內(nèi)碼表”的概念逃沿,可以切換到相應語言的一個內(nèi)碼表,這樣才能顯示相應語言的字母幻锁。在這種情況下凯亮,如果使用多語種,那么就需要頻繁的在內(nèi)碼表內(nèi)進行切換哄尔。

綜上可以總結(jié)為假消,需要一部足夠大的字典來標識所有的字符。最終岭接,美國人意識到他們應該提出一種標準方案來展示世界上所有語言中的所有字符富拗,出于這個目的,Unicode誕生了鸣戴。

Unicode是什么

Unicode 當然是一本很厚的字典啃沪,記錄著世界上所有字符對應的一個數(shù)字(code point)。具體是怎樣的對應關系窄锅,又或者說是如何進行劃分的创千,就不是我們考慮的問題了,我們只用知道 Unicode 給所有的字符指定了一個數(shù)字用來表示該字符。

它僅僅只是一個字符集签餐,規(guī)定了符合對應的二進制代碼寓涨,至于這個二進制代碼如何存儲則沒有任何規(guī)定。它的想法很簡單氯檐,就是為每個字符規(guī)定一個 用來表示該字符的數(shù)字,僅此而已体捏。

Unicode 是一本很厚的字典冠摄,她將全世界所有的字符定義在一個集合里。這么多的字符不是一次性定義的几缭,而是分區(qū)定義河泳。每個區(qū)可以存放 65536 個(216216)字符,稱為一個平面(plane)年栓。目前拆挥,一共有 17 個(2^5)平面,也就是說某抓,整個 Unicode 字符集的大小現(xiàn)在是2^21,當然實際沒有這么多纸兔。

最前面的 65536 個字符位,稱為基本平面(簡稱 BMP )否副,它的碼點范圍是從 0 到 2^16?1汉矿,寫成 16 進制就是從 U+0000 到 U+FFFF。所有最常見的字符都放在這個平面备禀,這是 Unicode 最先定義和公布的一個平面洲拇。剩下的字符都放在輔助平面(簡稱 SMP ),碼點范圍從 U+010000 到 U+10FFFF

所以unicode的code point范圍用十六進制標識為:

0x0000 0000 -- 0x0010 FFFF

Unicode 編碼

為了較好的解決 Unicode 的編碼問題曲尸, UTF-8 和 UTF-16 兩種當前比較流行的編碼方式誕生了赋续。當然還有一個 UTF-32 的編碼方式,也就是上述那種定長編碼另患,字符統(tǒng)一使用 4 個字節(jié)纽乱,雖然看似方便,但是卻不如另外兩種編碼方式使用廣泛柴淘。

UTF-8編碼

UTF-8 是一個非常驚艷的編碼方式迫淹,漂亮的實現(xiàn)了對 ASCII 碼的向后兼容,以保證 Unicode 可以被大眾接受为严。

UTF-8 是目前互聯(lián)網(wǎng)上使用最廣泛的一種 Unicode 編碼方式敛熬,它的最大特點就是可變長。它可以使用 1 - 4 個字節(jié)表示一個字符第股,根據(jù)字符的不同變換長度应民。編碼規(guī)則如下:

1、對于單個字節(jié)的字符,第一位設為 0诲锹,后面的 7 位對應這個字符的 Unicode 碼點繁仁。因此,對于英文中的 0 - 127 號字符归园,與 ASCII 碼完全相同黄虱。這意味著 ASCII 碼那個年代的文檔用 UTF-8 編碼打開完全沒有問題。

2庸诱、對于需要使用 N 個字節(jié)來表示的字符(N > 1)捻浦,第一個字節(jié)的前 N 位都設為 1,第 N + 1 位設為0桥爽,剩余的 N - 1 個字節(jié)的前兩位都設位 10朱灿,剩下的二進制位則使用這個字符的 Unicode 碼點來填充。

十六進制表示編碼范圍 UTF-8二進制表示 可以填充的二進制位數(shù)
0000 0000--0000 007F 0XXXXXXX 7
0000 0080--0000 07FF 110XXXXX 10XXXXXX 11
0000 0800--0000 FFFF 1110XXXX 10XXXXXX 10XXXXXX 16
0001 0000--0010 FFFF 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX 21

根據(jù)上面編碼規(guī)則對照表钠四,進行 UTF-8 編碼和解碼就簡單多了盗扒。下面以漢字“漢”為利,具體說明如何進行 UTF-8 編碼和解碼缀去。

“漢”的 Unicode 碼點是 0x6c49(110 1100 0100 1001)侣灶,通過上面的對照表可以發(fā)現(xiàn),0x0000 6c49 位于第三行的范圍朵耕,那么得出其格式為 1110xxxx 10xxxxxx 10xxxxxx炫隶。接著,從“漢”的二進制數(shù)最后一位開始阎曹,從后向前依次填充對應格式中的 x伪阶,多出的 x 用 0 補上。這樣处嫌,就得到了“漢”的 UTF-8 編碼為 11100110 10110001 10001001栅贴,轉(zhuǎn)換成十六進制就是 0xE6 0xB1 0x89

解碼的過程也十分簡單:如果一個字節(jié)的第一位是 0 熏迹,則說明這個字節(jié)對應一個字符檐薯;如果一個字節(jié)的第一位1,那么連續(xù)有多少個 1注暗,就表示該字符占用多少個字節(jié)

UTF-16編碼

UTF-16 編碼介于 UTF-32 與 UTF-8 之間坛缕,同時結(jié)合了定長和變長兩種編碼方法的特點。它的編碼規(guī)則很簡單:基本平面的字符占用 2 個字節(jié)捆昏,輔助平面的字符占用 4 個字節(jié)赚楚。也就是說,UTF-16 的編碼長度要么是 2 個字節(jié)(U+0000 到 U+FFFF)骗卜,要么是 4 個字節(jié)(U+010000 到 U+10FFFF)宠页。那么問題來了左胞,當我們遇到兩個字節(jié)時,到底是把這兩個字節(jié)當作一個字符還是與后面的兩個字節(jié)一起當作一個字符呢举户?

這里有一個很巧妙的地方烤宙,在基本平面內(nèi),從 U+D800 到 U+DFFF 是一個空段俭嘁,即這些碼點不對應任何字符躺枕。因此,這個空段可以用來映射輔助平面的字符兄淫。

輔助平面的字符位共有 2^20 (2^4個平面屯远,每個里面 2^16)個,因此表示這些字符至少需要 20 個二進制位捕虽。UTF-16 將這 20 個二進制位分成兩半,前 10 位映射在 U+D800 到 U+DBFF坡脐,稱為高位(H)泄私,后 10 位映射在 U+DC00 到 U+DFFF,稱為低位(L)备闲。這意味著晌端,一個輔助平面的字符,被拆成兩個基本平面的字符表示恬砂。

因此咧纠,當我們遇到兩個字節(jié),發(fā)現(xiàn)它的碼點在 U+D800 到 U+DBFF 之間泻骤,就可以斷定漆羔,緊跟在后面的兩個字節(jié)的碼點,應該在 U+DC00 到 U+DFFF 之間狱掂,這四個字節(jié)必須放在一起解讀演痒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市趋惨,隨后出現(xiàn)的幾起案子鸟顺,更是在濱河造成了極大的恐慌,老刑警劉巖器虾,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讯嫂,死亡現(xiàn)場離奇詭異,居然都是意外死亡兆沙,警方通過查閱死者的電腦和手機欧芽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挤悉,“玉大人渐裸,你說我怎么就攤上這事巫湘。” “怎么了昏鹃?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵尚氛,是天一觀的道長。 經(jīng)常有香客問我洞渤,道長阅嘶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任载迄,我火速辦了婚禮讯柔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘护昧。我一直安慰自己魂迄,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布惋耙。 她就那樣靜靜地躺著捣炬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绽榛。 梳的紋絲不亂的頭發(fā)上湿酸,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音灭美,去河邊找鬼推溃。 笑死,一個胖子當著我的面吹牛届腐,可吹牛的內(nèi)容都是我干的铁坎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼梯捕,長吁一口氣:“原來是場噩夢啊……” “哼厢呵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起傀顾,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤襟铭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后短曾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寒砖,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡缠劝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年艺晴,在試婚紗的時候發(fā)現(xiàn)自己被綠了庭瑰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斜做。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杭煎,靈堂內(nèi)的尸體忽然破棺而出哼拔,到底是詐尸還是另有隱情概行,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布儒鹿,位于F島的核電站化撕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏约炎。R本人自食惡果不足惜植阴,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望圾浅。 院中可真熱鬧掠手,春花似錦、人聲如沸狸捕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灸拍。三九已至魁衙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間株搔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工纯蛾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纤房,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓翻诉,卻偏偏與公主長得像炮姨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碰煌,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容