GB2312是對中國的開發人員來說很重要的一個詞匯,它的來龍去脈並不需要我在這裡贅述,隨便Goolge之便明白無誤。我只是想提一句,記得前一節說到編碼字符集和字符集編碼不是一回事,而有的字符集編碼又實際上沒有做任何事,GB2312正是這樣一種東西!
GB2312最初指的是一個編碼字符集,其中包含了ASCII所包含的英文字符,同時加入了6763個簡體漢字以及其他一些ASCII之外的符號。與Unicode有UTF-8和UTF-16一樣(當然, UTF-8和UTF-16也沒有被限定只能用來對Unicode進行編碼,實際上,你用它對視頻進行編碼都是可以的,只是編出的文件沒有播放器支持罷了,哈哈),GB2312也有自己的編碼方案,但這個方案直接使用一個字符在GB2312中的編號作為存儲值(與UTF-32的做法類似),也因此,這個編碼方案甚至沒有正式的名稱。我們日常說起GB2312的時候,常常即指這個字符集,也指這種編碼方案。
GBK是GB2312的後續標准,添加了更多的漢字和特殊符號,類似的是,GBK也是同時指他的字符集和他的編碼。
GBK還是現如今中文Windows操作系統的系統默認編碼(這正是幾乎所有網頁上的,文件裡的亂碼問題的根源)。
我們可以這樣來驗證,使用以下的Java代碼:
Stringencoding=System.getProperty("file.encoding");
System.out.println(encoding);
輸出結果為
GBK
(什麼?你的輸出不是這樣?怎麼可能?完了,我的牌子要砸了,等等,你用的繁體版XP?我說你這同志在這裡搗什麼亂?去!去!)
說到GB2312和GBK就不得不提中文網頁的編碼。盡管很多新開發的Web系統和新上線的注重國際化的網站都開始使用UTF-8,仍有相當一部分的中文媒體堅持使用GB2312和GBK,例如新浪的頁面。其中有兩點很值得注意。
第一,頁面中meta標簽的部分,常常可以見到
charset=GB2312
這樣的寫法,很不幸的是,這個“charset”其實是用來指定頁面使用的是什麼字符集編碼,而不是使用什麼字符集。例如你見到過有人寫“charset=UTF-8”,見到過有人寫“charset=ISO-8859-1”,但你見過有人寫“charset=Unicode”麼?當然沒有,因為Unicode是一個字符集,而不是編碼。
然而正是charset這個名稱誤導了很多程序員,真的以為這裡要指定的是字符集,也因而使他們進一步的誤以為UTF-8和UTF-16是一種字符集!(萬惡啊)好在XML中已經做出了修改,這個位置改成了正確的名稱:encoding。
第二,頁面中說的GB2312,實際上並不真的是GB2312(驚訝麼?)。我們來做個實驗,例如找一個GB2312中不存在的漢字“亸”(這個字確實不在GB2312中,你可以到GB2312的碼表中去找,保證找不到),這個字在GBK中。然後你把它放到一個html頁面中,試著在浏覽器中打開它,然後選擇浏覽器的編碼為“GB2312”,看到了什麼?它完全正常顯示!
結論不用我說你也明白了,浏覽器實際上使用的是GBK來顯示。
新浪的頁面中也有很多這樣的例子,到處都寫charset=GB2312,卻使用了無數個GB2312中並不存在的字符。這種做法對浏覽器顯示頁面並不成問題,但在需要程序抓取頁面並保存的時候帶來了麻煩,程序將不能依據頁面所“聲稱”的編碼進行讀取和保存,而只能盡量猜測正確的編碼。