鍍金池/ 教程/ Java/ 認(rèn)識字符集
編碼詳情
java編碼轉(zhuǎn)換過程
認(rèn)識字符集
javaWeb中的編碼解碼
認(rèn)識字符集
總結(jié)
java是如何編碼解碼的
解決URL中文亂碼問題
JSP頁面編碼過程

認(rèn)識字符集

java編碼中的中文問題是一個老生常談的問題了,每次遇到中文亂碼LZ要么是按照以前的經(jīng)驗修改,要么則是baidu.com來解決問題。閱讀許多關(guān)于中文亂碼的解決辦法的博文后,發(fā)現(xiàn)對于該問題我們都(更加包括我自己)沒有一個清晰明了的認(rèn)識,于是LZ想通過這系列博文(估計只有幾篇)來徹底分析、解決java中文亂碼問題,如有錯誤之處望各位同仁指出!當(dāng)然,此系列博文并非LZ完全原創(chuàng),都是在前輩基礎(chǔ)上總結(jié),歸納,如果雷同純屬借鑒……

問題起源

對于計算機而言,它僅認(rèn)識兩個0和1,不管是在內(nèi)存中還是外部存儲設(shè)備上,我們所看到的文字、圖片、視頻等等“數(shù)據(jù)”在計算機中都是已二進制形式存在的。不同字符對應(yīng)二進制數(shù)的規(guī)則,就是字符的編碼。字符編碼的集合稱為字符集。

在早期的計算機系統(tǒng)中,使用的字符是非常少的,他們只包括26個英文字母、數(shù)字符號和一些常用符號,對于這些字符進行編碼,用1個字節(jié)就足夠了,但是隨著計算機的不斷發(fā)展,為了適應(yīng)全世界其他各國民族的語言,這些少得可憐的字符編碼肯定是不夠的。于是人們提出了UNICODE編碼,它采用雙字節(jié)編碼,兼容英文字符和其他國家民族的雙字節(jié)字符編碼。

每個國家為了統(tǒng)一編碼都會規(guī)定該國家/地區(qū)計算機信息交換用的字符集編碼,為了解決本地字符信息的計算機處理,于是出現(xiàn)了各種本地化版本,引進LANG, Codepage 等概念。現(xiàn)在大部分具有國際化特征的軟件核心字符處理都是以 Unicode 為基礎(chǔ)的,在軟件運行時根據(jù)當(dāng)時的 Locale/Lang/Codepage 設(shè)置確定相應(yīng)的本地字符編碼設(shè)置,并依此處理本地字符。在處理過程中需要實現(xiàn) Unicode 和本地字符集的相互轉(zhuǎn)換。

同然,java內(nèi)部采用的就是Unicode編碼,所以在java運行的過程中就必然存在從Unicode編碼與相應(yīng)的計算機操作系統(tǒng)或者瀏覽器支持的編碼格式相互轉(zhuǎn)化的過程,這個轉(zhuǎn)換的過程有一系列的步驟,如果某個步驟出現(xiàn)錯誤,則輸出的文字就會是亂碼。

所以產(chǎn)生java亂碼的問題就在于JVM與對應(yīng)的操作系統(tǒng)/瀏覽器進行編碼格式轉(zhuǎn)換時出現(xiàn)了錯誤。

其實要解決java亂碼問題的方法還是比較簡單的,但是要究其原因,理解背后的原理還是需要了解

其實解決 JAVA 程序中的漢字編碼問題的方法往往很簡單,但理解其背后的原因,定位問題,還需要了解現(xiàn)有的漢字編碼和編碼轉(zhuǎn)換。

常見字符編碼

計算機要準(zhǔn)確的處理各種字符集文字,需要進行字符編碼,以便計算機能夠識別和存儲各種文字。常見的字符編碼主要包括:ASCII編碼、GB**編碼、Unicode。下面LZ就簡單地介紹下?。槭裁词呛唵谓榻B?因為LZ在網(wǎng)上查找資料想去了解字符編碼時,發(fā)現(xiàn)這個問題比我想象的復(fù)雜太多了,所以LZ需要另起一篇詳細(xì)介紹,所以各位看客就簡單看看吧!?。?/p>

1.ASCII編碼

ASCII,American Standard Code for Information Interchange,是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語和其他西歐語言。它是現(xiàn)今最通用的單字節(jié)編碼系統(tǒng)。

ASCII碼使用指定的7位或者8為二進制數(shù)字組合表示128或者256種可能的字符。標(biāo)準(zhǔn)的ASCII編碼使用的是7(2^7 = 128)位二進制數(shù)來表示所有的大小寫字母、數(shù)字和標(biāo)點符號已經(jīng)一些特殊的控制字符,最前面的一位統(tǒng)一規(guī)定為0。其中0~31及127(共33個)是控制字符或通信專用字符,32~126(共95個)是字符(32是空格),其中48~57為0到9十個阿拉伯?dāng)?shù)字,65~90為26個大寫英文字母,97~122號為26個小寫英文字母,其余為一些標(biāo)點符號、運算符號等。

http://wiki.jikexueyuan.com/project/java-chinese-garbled-solution/images/1.1.png" alt="" />

http://wiki.jikexueyuan.com/project/java-chinese-garbled-solution/images/1.2.png" alt="" />

2.GBK***編碼

ASCII最大的缺點就是顯示字符有限,他雖然解決了部分西歐語言的顯示問題,但是對更多的其他語言他實在是無能為了。隨著計算機技術(shù)的發(fā)展,使用范圍越來越廣泛了,ASCII的缺陷越來越明顯了,其他國家和地區(qū)需要使用計算機,必須要設(shè)計一套符合本國/本地區(qū)的編碼規(guī)則。例如為了顯示中文,我們就必須要設(shè)計一套編碼規(guī)則用于將漢字轉(zhuǎn)換為計算機可以接受的數(shù)字系統(tǒng)的數(shù)。

GB2312,用于漢字處理、漢字通信等系統(tǒng)之間的信息交換,通行于中國大陸。它的編碼規(guī)則是:小于127的字符的意義與原來相同,但兩個大于127的字符連在一起時,就表示一個漢字,前面的一個字節(jié)(他稱之為高字節(jié))從0xA1用到 0xF7,后面一個字節(jié)(低字節(jié))從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。雖然GB2312收錄了這么多漢子,他所覆蓋的使用率可以達到99%,但是對于那些不常見的漢字,例如人名、地名、古漢語,它就不能處理了,于是就有下面的GBK、GB 18030的出現(xiàn)。(點擊GB2312簡體中文編碼表查看)。

GB18030,全稱:國家標(biāo)準(zhǔn)GB 18030-2005《信息技術(shù) 中文編碼字符集》,是我國計算機系統(tǒng)必須遵循的基礎(chǔ)性標(biāo)準(zhǔn)之一,GB18030有兩個版本:GB18030-2000和GB18030-2005。GB18030-2000是GBK的取代版本,它的主要特點是在GBK基礎(chǔ)上增加了CJK統(tǒng)一漢字?jǐn)U充A的漢字。

GB 18030主要有以下特點:

  • 與UTF-8相同,采用多字節(jié)編碼,每個字可以由1個、2個或4個字節(jié)組成。
  • 編碼空間龐大,最多可定義161萬個字符。
  • 支持中國國內(nèi)少數(shù)民族的文字,不需要動用造字區(qū)。
  • 漢字收錄范圍包含繁體漢字以及日韓漢字

http://wiki.jikexueyuan.com/project/java-chinese-garbled-solution/images/1.3.jpg" alt="" />

GBK,漢字編碼標(biāo)準(zhǔn)之一,全稱《漢字內(nèi)碼擴展規(guī)范》,它 向下與 GB 2312 編碼兼容,向上支持 ISO 10646.1 國際標(biāo)準(zhǔn),是前者向后者過渡過程中的一個承上啟下的標(biāo)準(zhǔn)。它的編碼范圍如下圖:

http://wiki.jikexueyuan.com/project/java-chinese-garbled-solution/images/1.4.png" alt="" />

3.Unicode編碼

正如前面前面所提到的一樣,世界存在這么多國家,也存在著多種編碼風(fēng)格,像中文的GB232、GBK、GB18030,這樣亂搞一套,雖然在本地運行沒有問題,但是一旦出現(xiàn)在網(wǎng)絡(luò)上,由于互不兼容,訪問則會出現(xiàn)亂碼。為了解決這個問題,偉大的Unicode編碼騰空出世。

Unicode編碼的作用就是能夠使計算機實現(xiàn)夸平臺、跨語言的文本轉(zhuǎn)換和處理。它幾乎包含了世界上所有的符號,并且每個符號都是獨一無二的。在它的編碼世界里,每一個數(shù)字代表一個符號,每一個符號代表了一個數(shù)字,不存在二義性。

Unicode編碼又稱統(tǒng)一碼、萬國碼、單一碼,它是業(yè)界的一種標(biāo)準(zhǔn),是為了解決傳統(tǒng)的字符編碼方案的局限而產(chǎn)生的,它為每種語言中的每個字符設(shè)定了統(tǒng)一并且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉(zhuǎn)換、處理的要求。同時Unicode是字符集,它存在很多幾種實現(xiàn)方式如:UTF-8、UTF-16.

UTF-8

互聯(lián)網(wǎng)的普及,強烈要求出現(xiàn)一種統(tǒng)一的編碼方式。UTF-8就是在互聯(lián)網(wǎng)上使用最廣的一種unicode的實現(xiàn)方式。其他實現(xiàn)方式還包括UTF-16和UTF-32,不過在互聯(lián)網(wǎng)上基本不用。重復(fù)一遍:UTF-8是Unicode的實現(xiàn)方式之一。

UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節(jié)表示一個符號,根據(jù)不同的符號而變化字節(jié)長度。 UTF-8的編碼規(guī)則很簡單,只有兩條: 1)對于單字節(jié)的符號,字節(jié)的第一位設(shè)為0,后面7位為這個符號的unicode碼。因此對于英語字母,UTF-8編碼和ASCII碼是相同的。 2)對于n字節(jié)的符號(n>1),第一個字節(jié)的前n位都設(shè)為1,第n+1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。

推薦閱讀

此篇博文只是開篇之作,啟下之用, 對字符集的介紹也只是簡簡單單,沒有太多的描述,因為LZ在查字符集的資料過程中發(fā)現(xiàn)字符集真的是太復(fù)雜了,LZ有點兒駕馭不了,需要仔細(xì)研究,然后寫一篇較為詳細(xì)的博文!各位敬請期待!!

參考文獻:

字符集和字符編碼:http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html 百度百科 ASCII:http://baike.baidu.com/view/15482.htm

百度百科:GB2312:http://baike.baidu.com/view/443268.htm?fromtitle=GB2312&fromid=483170&type=syn

百度百科:GB18030:http://baike.baidu.com/view/889058.htm

百度百科:GBK:http://baike.baidu.com/view/931619.htm?fromtitle=GBK&fromid=481954&type=search

百度百科:Unicode:http://baike.baidu.com/view/40801.htm

百度百科:UTF-8:http://baike.baidu.com/view/25412.htm