微軟本著顧客就是上帝的原則,就把賣給中國人的有系統(tǒng)默認(rèn)使用GBK編碼,賣給韓國人的系統(tǒng)默認(rèn)使用EUC-KR編碼,其他國家也是如此。
但是為了避免廣大消費(fèi)者誤會(huì)賣給我們的系統(tǒng)功能有差異,微軟就把統(tǒng)一默認(rèn)編碼都顯示成ANSI。
在我們的電腦里面,ANSI也就是我們的GBK系列的編碼,當(dāng)我們用記事本另存的時(shí)候在下面就可以看到。
關(guān)于這個(gè)記事本,有個(gè)很注明的奇怪現(xiàn)象,當(dāng)你在windows的記事本里新建一個(gè)文件,輸入聯(lián)通這兩個(gè)字后,保存,關(guān)閉。
然后再次打開,你會(huì)發(fā)現(xiàn)這兩個(gè)字變成了亂碼。
有人說這就是聯(lián)通之所以干不過移動(dòng)的原因,其實(shí)這是因?yàn)镚BK編碼與UTF-8編碼產(chǎn)生了編碼沖撞的原因。
Unicode UTF-8
0000 - 007F 0XXXXXXX
0080 - 07FF 110XXXXX 10XXXXXX
0800 - FFFF 1110XXXX 10XXXXXX 10XXXXXX
上面這一段就是從Unicode到UTF-8的轉(zhuǎn)換規(guī)則。當(dāng)然是按十六進(jìn)制分的。
Unicode編碼中從0000到007F,對應(yīng)UTF-8中的二進(jìn)制編碼,就是以0開頭,占用一個(gè)字節(jié)。
Unicode編碼中從0080到07FF這段編碼對應(yīng)的是UTF-8中的110開頭的一個(gè)字節(jié),10開頭的一個(gè)字節(jié),兩個(gè)字節(jié)
0800到FFFF這段編碼,對應(yīng)的是UTF-8中的1110開頭的1個(gè)字節(jié),10開頭的一個(gè)字節(jié),還有一個(gè)10開頭的一個(gè)字節(jié),這里要用三個(gè)字節(jié)。
列入仙這個(gè)字,Unicode編碼是4ED9,4ED9在0800和FFFF之間,所以需要這個(gè)三個(gè)字節(jié)的模板。
4ED9轉(zhuǎn)換成二進(jìn)制是0100 1110 1101 1001 ,把這個(gè)比特流按三字節(jié)模板拆,就變成了這樣,依次替換模板中的X,得到1110-0100 10-111011 10-011001。
再轉(zhuǎn)成16進(jìn)制,就變成了E4BB99。
仙---->4ED9---->1110-0100 10-111011 10-011001
1110-0100 10-111011 10-011001--->E4BB99
這其實(shí)就是UTF-8的編碼,而當(dāng)你新建一個(gè)文本文件時(shí),記事本編碼默認(rèn)是ANSI,前面我們說過ANSI在我們電腦里其實(shí)就是GB系列編碼方式。
在這種編碼下,聯(lián)通的內(nèi)碼是:C1AA CDA8.這也是16進(jìn)制的。
前面我們學(xué)進(jìn)制轉(zhuǎn)換的時(shí)候知道,每四位二進(jìn)制可以轉(zhuǎn)換成1位十六進(jìn)制,也就是說每兩位十六進(jìn)制就是一個(gè)字節(jié)。
C1就是第一個(gè)字節(jié),轉(zhuǎn)成二進(jìn)制就是110 0001。
AA是第二個(gè)字節(jié),轉(zhuǎn)成二進(jìn)制就是1010 1010。
CD是第三個(gè)字節(jié),轉(zhuǎn)成二進(jìn)制就是1100 1101。
A8是第四個(gè)字節(jié),轉(zhuǎn)成二進(jìn)制是1010 1000。
C1--->1100 0001
AA--->1010 1010
CD--->1100 1101
A8--->1010 1000
我們來看第三四個(gè)字節(jié)的開頭部分,都是110和10,正好與UTF-8規(guī)則里的兩字節(jié)模板是一致的。
于是再次打開這個(gè)文件的時(shí)候,及時(shí)本會(huì)自動(dòng)識(shí)別編碼方式,它就誤認(rèn)為這是一個(gè)UTF-8編碼的文件,會(huì)把第一個(gè)字節(jié)的110和第二個(gè)字節(jié)的10去掉。于是就得到了00001 101010。
再把各位對齊,補(bǔ)上前面的0,就得到了0000 0000 0110 1010,這個(gè)二進(jìn)制就轉(zhuǎn)成十六進(jìn)制就變成了006A。
Unicode的006A也就是小寫的字母j,而之后的兩個(gè)字節(jié)用UTF-8解碼之后是0368,這個(gè)字符什么也不是。
0000 0000 0110 1010--->006A--->j
0000 0011 0110 1000--->0368--->不存在
這就是聯(lián)通兩個(gè)字的文件沒有辦法在記事本里正常顯示的原因。如果你在聯(lián)通后面輸入幾個(gè)字,其他的字的編碼不見得有恰好是110和10開始的字節(jié),這樣再次打開時(shí)記事本就不會(huì)堅(jiān)持這是一個(gè)UTF-8編碼的文件。
而會(huì)用ANSI的方式解讀,這是亂碼就不會(huì)出現(xiàn)了。
未經(jīng)允許不得轉(zhuǎn)載:445IT之家 » Python 記事本寫‘聯(lián)通’亂碼的原因