為什么會出現(xiàn) Unicode膊夹?
最開始美國人發(fā)明的電腦层释,它們只有 26
個英文字母截驮,再夾雜著一些其他特殊字符(&
¥
#
等)笑陈,所有字符加起來也不會超過 256
個字符,所以它們最開始使用 1
個字節(jié)(8
個 bit
位葵袭,一共可以表示 256
個字符)進(jìn)行字符的編碼(ASCII
碼)涵妥。
大家要知道,計算機是不認(rèn)識我們?nèi)祟愝斎氲娜魏巫址?code>a,
b
,c
,d
,趙
,錢
,孫
,李
,?
,?
,?
,?
等)坡锡,計算機只認(rèn)識0101
的二進(jìn)制蓬网,所以我們需要有一套字符集,將所有的字符都映射為二進(jìn)制編碼鹉勒,然后才能存儲到計算機中帆锋,反過來,從二進(jìn)制編碼也可以得到對應(yīng)的字符禽额,前提是你必須知道它使用的是哪種字符集锯厢。
至于為什么會出現(xiàn) Unicode
字符集,是因為各國相繼都推出了針對自己國家文字的字符集規(guī)則,比如中國自己推出的 GBK
实辑、GB2312
等臣疑,如果一個文件里邊即使用了中文,又使用了韓文徙菠、日文讯沈,那么我這個文件該如何編碼?
所以婿奔,基于萬物歸一的思想缺狠,推出了 Unicode
字符集編碼。
Unicode 是什么萍摊?
Unicode
只是一套字符集挤茄,和 ASCII
碼字符集一樣,是一個映射字符和二進(jìn)制的關(guān)系表冰木。
Unicode 和 UTF-8 是什么關(guān)系穷劈?
Unicode
本身只規(guī)定了每個字符的數(shù)字編號是多少,并沒有規(guī)定這個編號如何存儲踊沸?
有的人就說了歇终,和 ASCII
一樣啊,直接將編號轉(zhuǎn)換成二進(jìn)制存儲就可以了逼龟。
是的评凝,這樣是可以,這些都是人為來規(guī)定的腺律。
編號如何對應(yīng)到二進(jìn)制表示呢奕短? Unicode
給出的是類似于插件式的轉(zhuǎn)換方式,可以有多種選擇方式匀钧,這些插件就是這里說的 UTF-8
翎碑、UTF-16
、UTF-32
等之斯。
UTF-32
UTF-32
是最簡單的編碼日杈,也就是上面所說的直接將編號轉(zhuǎn)換成二進(jìn)制存儲。使用 ·4
· 個字節(jié)表示吊圾,處理單元為 4
個字節(jié)(即一次需要拿到 4
個字節(jié)才能解碼得到正確的信息)
但是這種方式的編碼會帶來另外一個問題达椰,大端序/小端序問題,因為它的處理單元是 4
個字節(jié)项乒。
UTF-16
UTF-16
使用變長字節(jié)啰劲,U+0000
到 U+FFFF
的字符(常用字符集),直接用兩個字節(jié)表示檀何;編號在 U+10000
到 U+10FFFF
之間的字符蝇裤,需要用四個字節(jié)表示廷支。
這種編碼方式同樣存在大端序/小端序問題。
UTF-8
UTF-8
同樣也使用的是變長字節(jié)表示栓辜,使用的字節(jié)個數(shù)從 1-4
個字節(jié)不等恋拍,編號小的使用的字節(jié)少,編號大的使用的字節(jié)多藕甩。
UTF-8
的編碼單元是 1
個字節(jié)(8 bit
位)施敢,所以不需要考慮字節(jié)序問題。
PS:編碼單元是 1
個字節(jié)表示說狭莱,1
個字節(jié)就能表達(dá)某一個具體的含義僵娃。
5 個事實
- 計算機中的所有內(nèi)容都是字節(jié)。程序的輸入輸出都是必須是字節(jié)腋妙。
- 字節(jié)本身是沒有含義的默怨,需要我們給字節(jié)約定一些含義,大家都遵循這個約定(例如:ASCII 碼)
- 世界上的所有文字符號骤素,肯定是超過 256 個的(也就是一個字節(jié)能表示的最大長度)
- 字節(jié)和Unicode都很重要匙睹,你需要處理他們兩個之間的關(guān)系。
- 不能認(rèn)為任何東西都是字節(jié)或者都是Unicode济竹,你需要明確的轉(zhuǎn)換他們痕檬。
- 字節(jié)字符串的編碼類型,是不能通過測試來確定的规辱。
- 需要通過其他明確的方式來確定谆棺。比如說HTTP等協(xié)議就包含了編碼格式的說明栽燕。
- 有時可能會被告知字節(jié)字符串的錯誤的編碼格式罕袋,所以在解碼的時候會導(dǎo)致亂碼。
3 個技巧
- 程序內(nèi)部的字節(jié)就不需要處理了(可能是程序自己將Unicode轉(zhuǎn)換成字節(jié)的)碍岔,但是進(jìn)出程序的數(shù)據(jù)務(wù)必進(jìn)行處理浴讯,進(jìn)入程序時候?qū)⒆止?jié)decode成Unicode,出程序的時候?qū)nicode encode成字節(jié)蔼啦。就好比一個三明治榆纽。
- 必須知道你即將處理的數(shù)據(jù)是什么類型的?如果你即將處理的數(shù)據(jù)類型是字節(jié)字符串捏肢,你應(yīng)該知道他是哪種編碼類型編碼的奈籽?
- bebug的時候不應(yīng)該使用print來查看數(shù)據(jù)是什么,應(yīng)該看數(shù)據(jù)的type是什么鸵赫?
- 測試對Unicode的支持衣屏。