標籤:
編碼問題一直困擾著我,每次遇到亂碼或者編碼問題,網上一查,問題解決了,但是實際的原理並沒有搞懂,每次遇到,都是什麼頭疼。
決定徹徹底底的一次性解決編碼問題。
1.為什麼要編碼
電腦的基本單元是位元組,一個位元組是8bit。一個位元組的範圍是0~255。
人類要表示的符號肯定比256個多,所以無法用一個位元組來表示這個多的符號。
你想想,光漢字就有幾千個。
要解決這個矛盾,有了一個新的資料結構:char。char也就是字元,最長16bit,最短為8bit。一個字元的最大長度是16bit。一個字元的範圍是0~2的16次方。
所以一個char型的資料結構,可以表示這個地球上的所有字元。
但是電腦它不會為你改變啊,它的基本單元還是位元組,8bit。所以如何把一個最長為16bit的char字元表示成為一個或者若干個8bit長的byte位元組,
這個過程就需要編碼。
2.如何翻譯
各種語言交流,都需要經過翻譯。一個長為16bit的char字元表示成為一個或者若干個8bit長的byte位元組,
電腦中提供了很多翻譯方式:ASCII,ISO-8859-1,GB2312,GBK,UTF-8,UTF-16
上面的幾種編碼方式都可以看成是字典,它們規定了轉化的規則,按照這個規則就可以讓電腦正確通過位元組的來表示我們自己定義的字元char這種資料類型。
ASCII碼:
ASCII碼,總共128個。由於ASCII碼只有128個,所以可以用一個8bit長的位元組表示,也可以用一個16bit長的字元表示。
0~31表示的控制字元如換行,斷行符號,刪除等,32~126是列印字元,如大寫字母,小寫字母等。
ASCII碼是單位元組編碼,也就是一個8bit長的char字元或者一個8bit的byte字元用一個位元組來編碼。
ISO-8859-1:
128個字元對於只使用英語的國家來說是夠用了,但是對於那麼西歐國家的語言來說就不夠用了,因為他們國家的語言中,除了英語字母,還有其他的字元。
於是ISO組織在ASCII碼基礎上制定了一系列的標準來擴充ASCII碼,它們是ISO-8859-1至ISO-8859-15。其中ISO-8859-1涵蓋了大多數的西歐語言字元,
所以應用的最為廣泛。
ISO-8859-1也是單位元組編碼,也就是一個8bit長的char字元用一個位元組來編碼。也就是擴充ASCII碼之後的ISO-8859-1,總共可以表示256個字元。
GB2312:
GB2312的全稱是《資訊技術 中文編碼字元集》,GB2312是雙位元組編碼,也就是一個16bit長的char字元用兩個位元組來編碼。
GB2312可以表示682個符號和6763個漢字。
GBK:
GBK的全稱是《漢字內碼擴充規範》,它的出現是為了擴充GB2312,以表示更多的漢字。
GBK是雙位元組編碼,也就是一個16bit長的char字元用兩個位元組來編碼。
GBK可以表示21003個漢字。
UTF-16:
說到UTF必須提到Unicode,ISO試圖建立一個全新的超語言字典,世界上所有的語言都可以通過這個字典來相互翻譯,而這就是Unicode。
UTF-16以及下面提到的UTF-8都是Unicode的不同實現形式。
UTF-16是雙位元組編碼,也就是一個16bit長的char字元用兩個位元組來編碼。
UTF-8:
UTF-16統一使用兩個位元組來表示一個字元,雖然在表示上非常簡單,方便,但是也有缺點,有很多的字元用一個位元組就可以表示了,但是使用兩個位元組來表示,造成了
儲存空間的浪費。UTF-8則採用了一種變長的表示技術,每個編碼地區有不同的字元長度。不同類型的字元可以由1~6個位元組來表示。
UTF-8有如下的編碼規則:
如果是一個位元組長度的byte或者8bit長的char,最高位為0,則表示這是一個ASCII字元,UTF-8用單位元組來表示。
如果一個位元組以11開頭,則連續的1的個數暗示這個字元的位元組數。110XXXXX則表示這是char字元的第一個位元組,這個char字元由兩個位元組組成,這個char字元16bit長,
UTF-8需要用兩個位元組或者更多位元組來編碼這個字元。
如果一個位元組以10開頭,表名這個位元組不是char字元的第一個位元組,前一個位元組是這個char字元的第一個位元組,也暗示這個char字元由兩個位元組組成,這個char字元16bit長,
UTF-8需要使用兩個或者更多的位元組來編碼這個字元。
3.
深入分析Java Web中的編碼問題