【转】ANSI与GB2312的编码问题
ANSI與GB2312的編碼問題
前兩天和Francis討論字符編碼的問題一直到深夜1點(diǎn),主要是為了解決php讀取文件的一個(gè)問題。可惜最后這個(gè)問題暫時(shí)沒解決,先拋開這個(gè)問題,我在這里總結(jié)一下我對(duì)字符編碼的認(rèn)識(shí)。
文件編碼與字符編碼
首先明確一點(diǎn),文件不存在什么編碼(歸根結(jié)底文件都是二進(jìn)制文件,用ue打開可以看到都是一個(gè)個(gè)的16進(jìn)制數(shù)),只有文件中的字符才可以說編碼。
編碼與解碼過程
字符通過某種編碼組織起來存到文件里面,計(jì)算機(jī)通過這種編碼解析解析文件,根據(jù)解析出來的文字繪制圖片顯示到顯示設(shè)備中,這樣我們就看到了文字。
常見編碼介紹
ansi編碼
最初的計(jì)算機(jī)是又8個(gè)晶體管,通過晶體管的開合與排列可以表示數(shù)種狀態(tài),所以一個(gè)字節(jié)就定義為8bit,而一個(gè)bit只能有0,1開關(guān)的表示,2的8次方是256,所以最初的計(jì)算機(jī)只能表示256種狀態(tài)。
人們定義了前32個(gè)為狀態(tài)字符比如翻頁(yè),換行,發(fā)出(嘟)的聲音等,后來人們?yōu)榱擞糜?jì)算機(jī)存儲(chǔ)文字,又把空格,英文字母,數(shù)字等加進(jìn)了進(jìn)來,總共使用了127個(gè),這時(shí)候大家把這個(gè)存儲(chǔ)方案叫做ANSI的ASCII編碼[American Standard Code for Information Interchange,美國(guó)信息互換標(biāo)準(zhǔn)代碼](http://www.dreamdu.com/xhtml/ascii/),這個(gè)表存儲(chǔ)英文已經(jīng)沒有 問題了,但是127個(gè)里并不包含其它歐洲國(guó)際的文字,人們又繼續(xù)擴(kuò)展ASCII表的內(nèi)容,加入了一些字符,與一些畫表格的符號(hào),直接擴(kuò)展到255個(gè)。
GB2312與GBK
國(guó)人發(fā)現(xiàn)只使用ASCII表根本無法表示漢字!怎么辦?沒有什么能難道我們!于是我們發(fā)明了GB2312編碼,此編碼完全忽略了ASCII表中 127位后面的內(nèi)容,127位前面的內(nèi)容保留,如果兩個(gè)字節(jié)同時(shí)大于127(7F)就認(rèn)為這兩個(gè)字節(jié)表示一個(gè)漢字,同時(shí)像標(biāo)點(diǎn)、字母也都重新使用兩個(gè)字節(jié) 定義了一遍,這就是我們經(jīng)常說的 全角,這種方案可以表示6000種文字。
但是中國(guó)的文字太復(fù)雜6000個(gè)字也不夠用,人們開始擴(kuò)展GB2312,規(guī)定只要一個(gè)字節(jié)大于127,這個(gè)字節(jié)和后面的字節(jié)組合起來就代表一個(gè)漢字,這種編碼成為GBK,于是又增加了20000多個(gè)漢字!
現(xiàn)在明白meta的編碼信息里為什么有GB2312與GBK了吧?:)
<meta http-equiv="content-type" content="text/html; charset=GB2312" /> <meta http-equiv="content-type" content="text/html; charset=GBK" />這樣很多國(guó)家都開始定義自己的編碼了,日本,韓國(guó)等。甚至連中國(guó)的臺(tái)灣省都定義了一種編碼 BIG5。所以在當(dāng)時(shí)一個(gè)程序要想適應(yīng)多國(guó)語言簡(jiǎn)直要把人郁悶死。
如果搞過windows編程的人應(yīng)該知道,win里面有多字節(jié)字符集MBCS(multi-byte character set)的說法,而且MBCS包含兩種字符類型,單字節(jié)字符SBCS(single-byte characters set)和雙字節(jié)字符(double-byte characters set)DBCS。我們的GBK與GB2312都是DBCS。所以我們?cè)诰幊虝r(shí)經(jīng)常遇到一個(gè)中文字符等于兩個(gè)英文字符的事情。BIG5與日本韓國(guó)的編碼也 都屬于DBCS。
這下清楚了吧,根本沒什么ansi文件或gb2312文件,文件打開時(shí)會(huì)根據(jù)操作系統(tǒng)的編碼方式(就是安裝在操作系統(tǒng)中的編碼解析方式)來嘗試打開文件,如果安裝了中文編碼,就把a(bǔ)nsi文件當(dāng)作中文打開,如果日文編碼,就當(dāng)作日文打開。
UNICODE與UTF-8
ISO最后提出了UNICODE(Universal Multiple-Octet Coded Character Set,簡(jiǎn)稱 UCS)編碼來解決所有的問題。
UNICODE編碼方式規(guī)定使用兩個(gè)字節(jié)(16位)表示表示一個(gè)字符,算算2的16次方是多少?原來ANSI規(guī)定的都擴(kuò)充為2字節(jié),并且把所有已知的語言都編碼進(jìn)UNICODE。UNICODE可以表示65536個(gè)字符。
這下多國(guó)語言程序開始高興了,使用UNICODE全部搞定!于是微軟重現(xiàn)編輯windows內(nèi)核,完全使用UNICODE編碼,搞過win編程的人應(yīng)該都知道,以A或W結(jié)尾的函數(shù),還有靈巧的_T宏吧?
雖然UNICODE有很多優(yōu)點(diǎn),但是缺點(diǎn)也不少,我先總結(jié)我知道的兩點(diǎn):
1,狂占空間,以前一個(gè)字節(jié)可以表示,現(xiàn)在卻要用兩個(gè)字節(jié)了,網(wǎng)絡(luò)上有80%屬于英文字符,這下網(wǎng)絡(luò)幾乎要擴(kuò)大一倍!
所以又有人研究出來了UTF-8(Unicode Translation Format - 8)編碼,UNICODE轉(zhuǎn)換格式,對(duì)于常用字符使用單字節(jié),漢字等使用雙字節(jié)。8代表每次在網(wǎng)絡(luò)上傳輸8位,如果是UTF-16就是每次傳輸16位。搞 過網(wǎng)絡(luò)編程的朋友應(yīng)該知道,字節(jié)序(就是字節(jié)的排放順序)分為兩種,主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序,就是大頭(俗稱)在前,小頭在前的問題,在網(wǎng)絡(luò)上面?zhèn)鬏數(shù)牧?的字節(jié)序很可能是不一致的,于是需要使用一種方法通知接收端,傳輸流的字節(jié)序。有人發(fā)明了一種簡(jiǎn)單的方法,在每個(gè)流的開始加上FFEF或EFFF,分別主 機(jī)與網(wǎng)絡(luò)字節(jié)序,我們可以使用記事本保存一個(gè)UNICODE文件,再使用ue打開看看(HEX方式打開)。所以有時(shí)候網(wǎng)頁(yè)傳到網(wǎng)上,在網(wǎng)頁(yè)最開始的地方會(huì) 出現(xiàn)一個(gè)字符,這個(gè)有時(shí)候很令人費(fèi)解。
用記事本新建立兩個(gè)文件存為UNICODE與UNICODE big endian模式,輸入夢(mèng)之都,保存再用ue打開。
UNICODE
FF FE A6 68 4B 4E FD 90
UNICODE big endian
FE FF 68 A6 4E 4B 90 FD (觀察,沒兩個(gè)字節(jié)和上面的對(duì)比)
2,UNICODE與GBK等兩字節(jié)編碼完全不兼容,無法找到一種簡(jiǎn)單的方式轉(zhuǎn)換(只能使用查找表的方式)
這點(diǎn)我們可以使用記事本新建立兩個(gè)文件一個(gè)ansi的文件,另一個(gè)utf8的文件,分別寫入夢(mèng)之都 ,保存。使用ue的hex模式打開我們會(huì)看到。
UNICODE
FF FE A6 68 4B 4E FD 90
ansi
C3 CE D6 AE B6 BC
猜編碼
在windows系統(tǒng)中打開文件時(shí),是使用了猜的方式選擇解析文件內(nèi)容編碼系統(tǒng),如果文件開頭使用了FEFF或FFFE,win系統(tǒng)認(rèn)為 UNICODE編碼,否則為ANSI編碼,如果是ANSI編碼繼續(xù)分析,如果一個(gè)字節(jié)大于127,就證明這個(gè)字節(jié)與后面的字節(jié)組成了一個(gè)漢字。
所以windows中文系統(tǒng)下,如果ansi文件,那么就會(huì)用gb2312方式轉(zhuǎn)換,如果是日文系統(tǒng),就會(huì)使用日文方式轉(zhuǎn)變,但是絕對(duì)不能說ansi文件里面有中文字符就是gb2312!一個(gè)gb2312占用兩個(gè)字節(jié)。而utf8 win系統(tǒng)在前面加了幾個(gè)字節(jié)以示區(qū)別。
通過這種方式分析時(shí)會(huì)產(chǎn)生一個(gè)很著名的問題,如果用記事本輸入“聯(lián)通”保存,再打開,發(fā)現(xiàn)“聯(lián)通”兩個(gè)字沒了!為什么沒有了,大家可以自己分析一下。有人說這就是聯(lián)通競(jìng)爭(zhēng)不過移動(dòng)的原因。?
通過這篇文章解決的網(wǎng)頁(yè)設(shè)計(jì)中的問題
- 1,一個(gè)漢字等于兩個(gè)字符,對(duì)嗎?
- 2,為什么頁(yè)面或頁(yè)面的開始會(huì)有亂碼?
- 3,GB2312與GBK的區(qū)別
- 4,為什么英文多的網(wǎng)站使用UTF-8比GB2312省空間?
轉(zhuǎn)載于:https://www.cnblogs.com/aaaheng/archive/2012/05/16/2503580.html
總結(jié)
以上是生活随笔為你收集整理的【转】ANSI与GB2312的编码问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SELinux让php程序无法远程连接数
- 下一篇: Web移动应用调试工具——Weinre