計(jì)算機(jī)中的字是如何處理的?
如果你用放大鏡看一下,可以看出屏幕上的字是由一個(gè)一個(gè)的像素點(diǎn)組成的,每一個(gè)字符用一組像素點(diǎn)拼接出來(lái),這些像素點(diǎn)組成一幅圖像,變成了我們的文字,計(jì)算機(jī)又是如何將我們的文字保存起來(lái)的呢?是用一個(gè)個(gè)的點(diǎn)組成的圖像將文字保存起來(lái)的嗎?當(dāng)然不是,讓我們從英文開(kāi)始,由于英文是拼音文字,實(shí)際上所有的英文字符和符號(hào)加起來(lái)也不超過(guò)100個(gè),在我們的文字中存在著如此大量的重復(fù)符號(hào),這就意味著保存每個(gè)字符的圖像會(huì)有大量的重復(fù),比如 e 就是出現(xiàn)最多的符號(hào)等等。所以在計(jì)算機(jī)中,實(shí)際上不會(huì)保存字符的圖像。
什么是字符編碼?
由于我們的文字中存在著大量的重復(fù)字符,而計(jì)算機(jī)天生就是用來(lái)處理數(shù)字的,為了減少我們需要保存的信息量,我們可以使用一個(gè)數(shù)字編碼來(lái)表示每一個(gè)字符,通過(guò)對(duì)每一個(gè)字符規(guī)定一個(gè)唯一的數(shù)字代號(hào),然后,對(duì)應(yīng)每一個(gè)代號(hào),建立其相對(duì)應(yīng)的圖形,這樣,在每一個(gè)文件中,我們只需要保存每一個(gè)字符的編碼就相當(dāng)于保存了文字,在需要顯示出來(lái)的時(shí)候,先取得保存起來(lái)的編碼,然后通過(guò)編碼表,我們可以查到字符對(duì)應(yīng)的圖形,然后將這個(gè)圖形顯示出來(lái),這樣我們就可以看到文字了,這些用來(lái)規(guī)定每一個(gè)字符所使用的代碼的表格,就稱為編碼表。編碼就是對(duì)我們?nèi)粘J褂米址囊环N數(shù)字編號(hào)。
第一個(gè)編碼表 ASCII
在最初的時(shí)候,美國(guó)人制定了第一張編碼表 《美國(guó)標(biāo)準(zhǔn)信息交換碼》,簡(jiǎn)稱 ASCII,它總共規(guī)定了 128 個(gè)符號(hào)所對(duì)應(yīng)的數(shù)字代號(hào),使用了 7 位二進(jìn)制的位來(lái)表示這些數(shù)字。其中包含了英文的大小寫(xiě)字母、數(shù)字、標(biāo)點(diǎn)符號(hào)等常用的字符,數(shù)字代號(hào)從 0 至 127,ASCII 的表示內(nèi)容如下:
0 – 31 控制符號(hào)
32 空格
33-47 常用符號(hào)
48-57 數(shù)字
58-64 符號(hào)
65-90 大寫(xiě)字母
91-96 符號(hào)
97-127 小寫(xiě)字母
注意,32 表示空格,雖然我們?cè)偌埳蠈?xiě)字時(shí),只要手腕動(dòng)一下,就可以流出一個(gè)空格,但是,在計(jì)算機(jī)上,空格與普通得字符一樣也需要用一個(gè)編碼來(lái)表示,33-127 共95個(gè)編碼用來(lái)表示符號(hào),數(shù)字和英文的大寫(xiě)和小寫(xiě)字母。比如數(shù)字 1 所對(duì)應(yīng)的數(shù)字代號(hào)為 49,大寫(xiě)字母 A 對(duì)應(yīng)的代號(hào)為 65, 小寫(xiě)字母 a 對(duì)應(yīng)的代號(hào)為 97。所以,我們所寫(xiě)的代碼 hello, world 保存在文件中時(shí),實(shí)際上是保存了一組數(shù)字 104 101 108 108 111 44 32 119 111 114 108 100。我們?cè)俪绦蛑斜容^英文字符串的大小時(shí),實(shí)際上也是比較字符對(duì)應(yīng)的 ASCII 的編碼大小。
由于 ASCII 出現(xiàn)最早,因此各種編碼實(shí)際上都受到了它的影響,并盡量與其相兼容。
擴(kuò)展 ASCII 編碼 ISO8859
美國(guó)人順利解決了字符的問(wèn)題,可是歐洲的各個(gè)國(guó)家還沒(méi)有,比如法語(yǔ)中就有許多英語(yǔ)中沒(méi)有的字符,因此 ASCII 不能幫助歐洲人解決編碼問(wèn)題。
為了解決這個(gè)問(wèn)題,人們借鑒 ASCII 的設(shè)計(jì)思想,創(chuàng)造了許多使用 8 位二進(jìn)制數(shù)來(lái)表示字符的擴(kuò)充字符集,這樣我們就可以使用256種數(shù)字代號(hào)了,表示更多的字符了。在這些字符集中,從 0 - 127 的代碼與 ASCII 保持兼容,從 128 到 255 用于其它的字符和符號(hào),由于有很多的語(yǔ)言,有著各自不同的字符,于是人們?yōu)椴煌恼Z(yǔ)言制定了大量不同的編碼表,在這些碼表中,從 128 - 255 表示各自不同的字符,其中,國(guó)際標(biāo)準(zhǔn)化組織的 ISO8859 標(biāo)準(zhǔn)得到了廣泛的使用。
在 ISO8859 的編碼表中,編號(hào) 0 – 127 與 ASCII 保持兼容,編號(hào)128 – 159 共32個(gè)編碼保留給擴(kuò)充定義的 32 個(gè)擴(kuò)充控制碼,160 為空格, 161 -255 的 95 個(gè)數(shù)字用于新增加的字符代碼。編碼的布局與 ASCII 的設(shè)計(jì)思想如出一轍,由于在一張碼表中只能增加 95 種字符的代碼,所以 ISO8859 實(shí)際上不是一張碼表,而是一系列標(biāo)準(zhǔn),包括 14 個(gè)字符碼表。例如,西歐的常用字符就包含在 ISO8859-1字符表中。在 ISO8859-7種則包含了 ASCII 和現(xiàn)代希臘語(yǔ)字符。
問(wèn)題出現(xiàn)了!
ISO 的8859標(biāo)準(zhǔn)解決了大量的字符編碼問(wèn)題,但也帶來(lái)了新的問(wèn)題,比如說(shuō),沒(méi)有辦法在一篇文章中同時(shí)使用 ISO8859-1 和 ISO8859-7,也就是說(shuō),在同一篇文章中不能同時(shí)出現(xiàn)希臘文和法文,因?yàn)樗麄兊木幋a范圍是重合的。例如:在 ISO8859-1 中 217號(hào)編碼表示字符Ù ,而在 ISO8859-7中則表示希臘字符Ω,這樣一篇使用 ISO8859-1 保存的文件,在使用 ISO8859-7編碼的計(jì)算機(jī)上打開(kāi)時(shí),將看到錯(cuò)誤的內(nèi)容。為了同時(shí)處理一種以上的文字,甚至還出現(xiàn)了一些同時(shí)包含原來(lái)不屬于同一張碼表的字符的新碼表。
大字符集的煩惱
不管如何,歐洲的拼音文字都還可以用一個(gè)字節(jié)來(lái)保存,一個(gè)字節(jié)由8個(gè)二進(jìn)制的位組成,用來(lái)表示無(wú)符號(hào)的整數(shù)的話,范圍正好是 0 – 255。
但是,更嚴(yán)重的問(wèn)題出現(xiàn)在東方,中國(guó),朝鮮和日本的文字包含大量的符號(hào)。例如,中國(guó)的文字不是拼音文字,漢字的個(gè)數(shù)有數(shù)萬(wàn)之多,遠(yuǎn)遠(yuǎn)超過(guò)區(qū)區(qū) 256 個(gè)字符,因此 ISO 的 8859 標(biāo)準(zhǔn)實(shí)際上不能處理中文的字符。
通過(guò)借鑒 ISO8859 的編碼思想,中國(guó)的專家靈巧的解決了中文的編碼問(wèn)題。
既然一個(gè)字節(jié)的 256 種字符不能表示中文,那么,我們就使用兩個(gè)字節(jié)來(lái)表示一個(gè)中文,在每個(gè)字符的 256 種可能中,低于 128 的為了與 ASCII 保持兼容,我們不使用,借鑒 ISO8859的設(shè)計(jì)方案,只使用從 160 以后的 96 個(gè)數(shù)字,兩個(gè)字節(jié)分成高位和低位,高位的取值范圍從 176-247 共72個(gè),低位從 161 – 254共94這樣,兩個(gè)字節(jié)就有 72 * 94 = 6768種可能,也就是可以表示 6768 種漢字,這個(gè)標(biāo)準(zhǔn)我們稱為 GB2312-80。
6768 個(gè)漢字顯然不能表示全部的漢字,但是這個(gè)標(biāo)準(zhǔn)是在1980年制定的,那時(shí)候,計(jì)算機(jī)的處理能力,存儲(chǔ)能力都還很有限,所以在制定這個(gè)標(biāo)準(zhǔn)的時(shí)候,實(shí)際上只包含了常用的漢字,這些漢字是通過(guò)對(duì)日常生活中的報(bào)紙,電視,電影等使用的漢字進(jìn)行統(tǒng)計(jì)得出的,大概占常用漢字的 99%。因此,我們時(shí)常會(huì)碰到一些名字中的特殊漢字無(wú)法輸入到計(jì)算機(jī)中的問(wèn)題,就是由于這些生僻的漢字不在 GB2312 的常用漢字之中的緣故。
由于 GB2312 規(guī)定的字符編碼實(shí)際上與 ISO8859 是沖突的,所以,當(dāng)我們?cè)谥形沫h(huán)境下看一些西文的文章,使用一些西文的軟件的時(shí)候,時(shí)常就會(huì)發(fā)現(xiàn)許多古怪的漢字出現(xiàn)在屏幕上,實(shí)際上就是因?yàn)槲魑闹惺褂昧伺c漢字編碼沖突的字符,被我們的系統(tǒng)生硬的翻譯成中文造成的。
不過(guò),GB2312 統(tǒng)一了中文字符編碼的使用,我們現(xiàn)在所使用的各種電子產(chǎn)品實(shí)際上都是基于 GB2312 來(lái)處理中文的。
GB2312-80 僅收漢字6763個(gè),這大大少于現(xiàn)有漢字,隨著時(shí)間推移及漢字文化的不斷延伸推廣,有些原來(lái)很少用的字,現(xiàn)在變成了常用字,例如:朱镕基的“镕”字,未收入GB2312-80,現(xiàn)在大陸的報(bào)業(yè)出刊只得使用(金+容)、(金容)、(左金右容)等來(lái)表示,形式不一而同,這使得表示、存儲(chǔ)、輸入、處理都非常不方便,而且這種表示沒(méi)有統(tǒng)一標(biāo)準(zhǔn)。
為了解決這些問(wèn)題,全國(guó)信息技術(shù)化技術(shù)委員會(huì)于1995年12月1日《漢字內(nèi)碼擴(kuò)展規(guī)范》。GBK向下與GB2312完全兼容,向上支持ISO 10646國(guó)際標(biāo)準(zhǔn),在前者向后者過(guò)渡過(guò)程中起到的承上啟下的作用。GBK 亦采用雙字節(jié)表示,總體編碼范圍為8140-FEFE之間,高字節(jié)在81-FE之間,低字節(jié)在40-FE之間,不包括7F。在 GBK 1.0 中共收錄了 21886個(gè)符號(hào),漢字有21003個(gè)。
GBK 共收入21886個(gè)漢字和圖形符號(hào),包括:
* GB2312 中的全部漢字、非漢字符號(hào)。
* BIG5 中的全部漢字。
* 與ISO 10646相應(yīng)的國(guó)家標(biāo)準(zhǔn)GB13000中的其它CJK漢字,以上合計(jì)20902個(gè)漢字。
* 其它漢字、部首、符號(hào),共計(jì)984個(gè)。
微軟公司自Windows 95 簡(jiǎn)體中文版開(kāi)始支持GBK代碼,但目前的許多軟件都不能很好地支持GBK漢字。
GBK 編碼區(qū)分三部分:
* 漢字區(qū) 包括
GBK/2 :OXBOA1-F7FE, 收錄GB2312漢字6763個(gè),按原序排列;
GBK/3 :OX8140-AOFE,收錄CJK漢字6080個(gè);
GBK/4 :OXAA40-FEAO,收錄CJK漢字和增補(bǔ)的漢字8160個(gè)。
* 圖形符號(hào)區(qū) 包括
GBK/1 :OXA
GBK/5 :OXA840-A9AO,擴(kuò)除非漢字區(qū)。
* 用戶自定義區(qū)
即GBK區(qū)域中的空白區(qū),用戶可以自己定義字符。
GB18030 是最新的漢字編碼字符集國(guó)家標(biāo)準(zhǔn), 向下兼容 GBK 和 GB2312 標(biāo)準(zhǔn)。 GB18030 編碼是一二四字節(jié)變長(zhǎng)編碼。 一字節(jié)部分從 0x0~0x
不一樣的中文
中文的問(wèn)題好像也解決了,且慢,新的問(wèn)題又來(lái)了。
中國(guó)的臺(tái)灣省也在使用中文,但是由于歷史的原因,那里沒(méi)有使用大陸的簡(jiǎn)體中文,還在使用著繁體的中文,并且他們自己也制定了一套表示繁體中文的字符編碼,稱為 BIG5,不幸的是,雖然他們的也使用兩個(gè)字節(jié)來(lái)表示一個(gè)漢字,但他們沒(méi)有象我們兼容 ASCII 一樣兼容大陸的簡(jiǎn)體中文,他們使用了大致相同的編碼范圍來(lái)表示繁體的漢字。天哪! ISO8859 的悲劇又出現(xiàn)在同樣使用漢字的中國(guó)人身上了,同樣的編碼在大陸和臺(tái)灣的編碼中實(shí)際上表示不同的字符,大陸的玩家在玩臺(tái)灣的游戲時(shí),經(jīng)常會(huì)遇到亂碼的問(wèn)題,問(wèn)題根源就在于,大陸的計(jì)算機(jī)默認(rèn)字符的編碼就是 GB2312, 當(dāng)碰到臺(tái)灣使用 BIG5 編碼的文字時(shí),就會(huì)作出錯(cuò)誤的轉(zhuǎn)換。
由于歷史和文化的原因,日文和韓文中也包含許多的漢字,象漢字一樣擁有大量的字符,不幸的是,他們的字符編碼也同樣與中文編碼有著沖突,日文的游戲在大陸上一樣也會(huì)出現(xiàn)無(wú)法理解的亂碼。《中文之星》,《南極星》,《四通利方》就是用于在這些編碼中進(jìn)行識(shí)別和轉(zhuǎn)換的專用軟件。
互聯(lián)的時(shí)代
在二十世紀(jì)八十年代后期,互聯(lián)網(wǎng)出現(xiàn)了,一夜之間,地球村上的人們可以直接訪問(wèn)遠(yuǎn)在天邊的服務(wù)器,電子文件在全世界傳播,在一切都在數(shù)字化的今天,文件中的數(shù)字到底代表什么字?這可真是一個(gè)問(wèn)題。
UNICODE
實(shí)際上問(wèn)題的根源在于我們有太多的編碼表。
如果整個(gè)地球村都使用一張統(tǒng)一的編碼表,那么每一個(gè)編碼就會(huì)有一個(gè)確定的含義,就不會(huì)有亂碼的問(wèn)題出現(xiàn)了。
實(shí)際上,在80年代就有了一個(gè)稱為 UNICODE 的組織,這個(gè)組織制定了一個(gè)能夠覆蓋幾乎任何語(yǔ)言的編碼表,在 Unicode
由于要表示的字符如此之多,所以一開(kāi)始的 Unicode1.0編碼就使用連續(xù)的兩個(gè)字節(jié)也就是一個(gè)WORD 來(lái)表示編碼,比如“漢”的UCS 編碼就是 6C49。這樣在 Unicode 的編碼中就可以表示 256*256 = 65536 種符號(hào)了。
直接使用一個(gè)WORD 相當(dāng)于兩個(gè)字節(jié)來(lái)保存編碼可能是最為自然的 Unicode 編碼的方式,這種方式被稱為 UCS-2,也被稱為 ISO 10646,,在這種編碼中,每一個(gè)字符使用兩個(gè)字節(jié)來(lái)進(jìn)行表示,例如,“中” 使用 11598 來(lái)編碼,而大寫(xiě)字母 A 仍然使用 65 表示,但它占用了兩個(gè)字節(jié),高位用 0 來(lái)進(jìn)行補(bǔ)齊。
由于每個(gè)WORD 表示一個(gè)字符,但是在不同的計(jì)算機(jī)上,實(shí)際上對(duì) WORD 有兩種不同的處理方式,高字節(jié)在前,或者低字節(jié)在前,為了在UCS-2編碼的文檔中,能夠區(qū)分到底是高字節(jié)在前,還是低字節(jié)在前,使用 UCS-2 的文檔使用了一組不可能在UCS-2種出現(xiàn)的組合來(lái)進(jìn)行區(qū)分,通常情況下,低字節(jié)在前,高字節(jié)在后,通過(guò)在文檔的開(kāi)頭增加 FFFE 來(lái)進(jìn)行表示。高字節(jié)在前,低字節(jié)在后,稱為大頭在前,即Big Endian,使用 FFFE 來(lái)進(jìn)行表示。這樣,程序可以通過(guò)文檔的前兩個(gè)字節(jié),立即判斷出該文檔是否高字節(jié)在前。
Endian 這個(gè)詞出自 《格列佛游記》,小人國(guó)的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)要先吃大頭 big endian 還是小頭 little-endian,并由此發(fā)生了內(nèi)戰(zhàn)。
理想與現(xiàn)實(shí)
UCS-2 雖然理論上可以統(tǒng)一編碼,但仍然面臨著現(xiàn)實(shí)的困難。
首先,UCS-2 不能與現(xiàn)有的所有編碼兼容,現(xiàn)有的文檔和軟件必須針對(duì) Unicode 進(jìn)行轉(zhuǎn)換才能使用。即使是英文也面臨著單字節(jié)到雙字節(jié)的轉(zhuǎn)換問(wèn)題。
其次,許多國(guó)家和地區(qū)已經(jīng)以法律的形式規(guī)定了其所使用的編碼,更換為一種新的編碼不現(xiàn)實(shí)。比如在中國(guó)大陸,就規(guī)定 GB2312 是大陸軟件、硬件編碼的基礎(chǔ)。
第三,現(xiàn)在還有使用中的大量的軟件和硬件是基于單字節(jié)的編碼實(shí)現(xiàn)的,UCS-2 的雙字節(jié)表示的字符不能可靠的在其上工作。
新希望 UTF-8
為了盡可能與現(xiàn)有的軟件和硬件相適應(yīng),美國(guó)人又制定了一系列用于傳輸和保存Unicode 的編碼標(biāo)準(zhǔn) UTF,這些編碼稱為UCS 傳輸格式碼,也就是將 UCS 的編碼通過(guò)一定的轉(zhuǎn)換,來(lái)達(dá)到使用的目的。常見(jiàn)的有 UTF-7,UTF-8,UTF-16等。
其中 UTF-8 編碼得到了廣泛的應(yīng)用,UTF-8 的全名是UCS Transformation Format 8, 即 UCS 編碼的8位傳輸格式,就是使用單字節(jié)的方式對(duì) UCS 進(jìn)行編碼,使 Unicode 編碼能夠在單字節(jié)的設(shè)備上正常進(jìn)行處理。
UTF-8 編碼是變長(zhǎng)的編碼,對(duì)不同的 Unicode 可能編成不同的長(zhǎng)度
UCS-2 UTF-8
0000
0080-07FF 128- 2047 110xxxxx 10xxxxxx
0800-FFFF 2048-65535 1110xxxx 10xxxxxx 10xxxxxx
例如 1 的Unicode 編碼是 31 00,在 0-127之間,所以轉(zhuǎn)換后即為 31,而“中”字的UTF-8 Unicode 編碼為 11598,轉(zhuǎn)換成 UTF-8則為 e4 b8 ad。
實(shí)際上,ASCII 字符用 UTF-8 來(lái)表示后,與 ASCII 是完全一樣的,美國(guó)人又近水樓臺(tái)的把自己的問(wèn)題解決了。但其他的編碼就沒(méi)有這么幸運(yùn)了。
突破障礙 - Unicode 與 本地編碼的轉(zhuǎn)換
UTF-8 編碼解決了字符的編碼問(wèn)題,又可以在現(xiàn)有的設(shè)備上通行,因此,得到了廣泛的使用,
在人間
XML 中的問(wèn)題
XML 的設(shè)計(jì)目標(biāo)是實(shí)現(xiàn)跨網(wǎng)絡(luò),跨國(guó)界的信息表示,所以,在XML 設(shè)計(jì)之初,就規(guī)定 XML 文件的默認(rèn)編碼格式就是 UTF-8,也就是說(shuō),如果沒(méi)有特殊的說(shuō)明,XML文件將被視為 UTF-8 編碼。
然而,大部分的中文編輯軟件,是根據(jù)操作系統(tǒng)來(lái)決定編碼的方式的,所以,在寫(xiě)字板中直接輸入并保存的文件,將被保存為 GB2312 編碼,所以,在讀出 XML文件內(nèi)容時(shí),往往就會(huì)出現(xiàn)文件錯(cuò)誤的提示了。這種情況會(huì)出現(xiàn)在文件中有中文出現(xiàn)的時(shí)候,如果沒(méi)有中文,只有英文信息,就不會(huì)出現(xiàn)問(wèn)題。原因很簡(jiǎn)單,有中文時(shí),因?yàn)橹形牡木幋a并不是UTF-8 編碼,所以會(huì)造成沖突,沒(méi)有中文時(shí),英文的編碼在GB2312 中與ASCII是兼容的,而ASCII 與UTF-8 是完全一致的,所以不會(huì)出現(xiàn)問(wèn)題。這種情況也包括 UltraEdit 軟件。
但時(shí),專業(yè)的 XML編輯軟件會(huì)自動(dòng)將內(nèi)容保存為 UTF-8 編碼,不會(huì)有問(wèn)題。
在通過(guò)DOM或XSLT保存 XML 文件時(shí)也有著同樣的問(wèn)題。
默認(rèn)情況下,XML 的處理程序一般會(huì)將內(nèi)容作為 UTF-8 編碼進(jìn)行處理,所以保存下來(lái)的 XML 文件必須要用可以識(shí)別 UTF-8 的軟件來(lái)進(jìn)行查看,如Windows 的記事本。
Java 的處理
Java 的設(shè)計(jì)目標(biāo)是一次編寫(xiě),到處運(yùn)行,所以在 Java 的內(nèi)部對(duì)字符的處理采用了 UCS 來(lái)處理,因此 Java 的字符類型不再是 C++ 中的一個(gè)字節(jié),而使用兩個(gè)字節(jié)來(lái)保存一個(gè)字符。
但是,我們會(huì)發(fā)現(xiàn),在 Java 的文件流中保存為文件后,我們可以直接使用記事本或 UltraEdit 打開(kāi)察看。
在這里,Java 采用了一個(gè)靈巧的默認(rèn)轉(zhuǎn)換機(jī)制,當(dāng)需要將內(nèi)容中的字符保存到文件中時(shí),Java 會(huì)自動(dòng)的查看一下系統(tǒng)的本地編碼,系統(tǒng)的本地編碼可以在控制面板中查到,然后,自動(dòng)將 UCS 編碼的字符轉(zhuǎn)換為本地編碼,并進(jìn)行保存。當(dāng)需要從系統(tǒng)的文件系統(tǒng)中讀入一個(gè)文件時(shí),Java 通過(guò)查看系統(tǒng)的本地編碼來(lái)決定如何識(shí)別文件的內(nèi)容。這樣,Java 就可以在內(nèi)部使用 UCS, 但用戶可以直接使用本地編碼的文件了。
Java 在相應(yīng)的方法中,提供了額外的參數(shù),可以讓用戶自己來(lái)指定文件的編碼。
.Net 的處理
在微軟的 .Net 內(nèi)部,同樣使用 UCS 編碼,但是,在對(duì)文件進(jìn)行處理的時(shí)候,與Java 有一些區(qū)別,.Net 不查詢系統(tǒng)的本地編碼,而是直接使用磨人的 UTF-8 編碼進(jìn)行文件的處理,所以,你保存的中文內(nèi)容,在 UltraEdit 中可能就是亂碼,但是,如果你使用記事本打開(kāi)的話,就不會(huì)有問(wèn)題,因?yàn)?span lang="EN-US"> Windows 的記事本可以識(shí)別 UTF-8 的編碼。
.Net 軟件的配置文件使用 XML 格式,默認(rèn)的編碼一樣是 UTF-8 ,所以,必須使用可以識(shí)別 UTF-8 的軟件進(jìn)行處理,如:vs.net,記事本等。
在 .Net 中,網(wǎng)頁(yè)默認(rèn)處理編碼就是 UTF-8。
Web 中的問(wèn)題
網(wǎng)頁(yè)的編碼問(wèn)題主要有兩點(diǎn),一是網(wǎng)頁(yè)是如何編碼的,二是如何告訴瀏覽器如何編碼的。
第一個(gè)問(wèn)題,又可以分成靜態(tài)頁(yè)面和動(dòng)態(tài)頁(yè)面兩個(gè)問(wèn)題。
對(duì)靜態(tài)頁(yè)面,網(wǎng)頁(yè)的編碼要看你保存文件時(shí)的編碼選項(xiàng),多數(shù)的網(wǎng)頁(yè)編輯軟件可以讓你選擇編碼的類型,默認(rèn)為本地編碼,為了使網(wǎng)頁(yè)減少編碼的問(wèn)題,最好保存為 UTF-8 編碼格式。
對(duì)動(dòng)態(tài)頁(yè)面,如 Servlet 生成的頁(yè)面,在 HttpServletResponse 類中有一個(gè)方法 setContentType,可以通過(guò)參數(shù)來(lái)指定生成的頁(yè)面的類型和編碼,例如:response.setContentType("text/html; charset=utf-8");來(lái)指定生成的頁(yè)面的編碼類型。
對(duì) jsp 頁(yè)面可以通過(guò) <%@ page contentType="text/html;charset=gb2312" %> 來(lái)指定生成的頁(yè)面的編碼及類型。
第二個(gè)問(wèn)題,如何通知瀏覽器網(wǎng)頁(yè)的編碼類型。
瀏覽器收到只是一個(gè)字節(jié)流,它并不知道頁(yè)面是如何編碼的,因此,需要一個(gè)機(jī)制來(lái)告訴瀏覽器頁(yè)面的編碼類型,標(biāo)準(zhǔn)的機(jī)制是使用 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 來(lái)指定頁(yè)面的編碼,當(dāng)瀏覽器讀取頁(yè)面遇到這樣的指示時(shí),將使用這里制定的編碼方式重新加載頁(yè)面。
否則的話,瀏覽器將會(huì)試圖猜出頁(yè)面的編碼類型。
Tomcat 中的中文問(wèn)題
在 Tomcat 中,經(jīng)常遇到取回客戶端提交的信息是亂碼的問(wèn)題。
當(dāng)提交表單的時(shí)候,HTML頁(yè)面的Form標(biāo)簽會(huì)使情況變得更為復(fù)雜。瀏覽器的編碼方式取決于當(dāng)前頁(yè)面的編碼設(shè)定,對(duì)Form標(biāo)簽也照此處理。這意味著如果ASCII格式的HTML頁(yè)面用ISO-8859-1編碼,那么用戶在此頁(yè)面中將不能提交中文字符。所以,如果你的頁(yè)面使用的是 utf-8,那么 POST 的時(shí)候,也將使用 utf-8 。
由于 Tomcat 是美國(guó)人設(shè)計(jì)的,Tomcat 默認(rèn)使用ISO8859-1 編碼隊(duì)客戶端返回的內(nèi)容進(jìn)行解碼,由于編碼與內(nèi)容不一致,就會(huì)出現(xiàn)亂碼的 ??? 出現(xiàn),根據(jù)以上的分析,在服務(wù)器端讀取客戶端回送的內(nèi)容時(shí),需要首先設(shè)定回送內(nèi)容的編碼,然后再進(jìn)行信息的讀取,通過(guò)使用 HttpServletRequest 的方法 setCharacterEncoding("utf-8")先行設(shè)定信息的編碼類型。然后,就可以正確讀取內(nèi)容了。
總結(jié)
編碼問(wèn)題是信息處理的基本問(wèn)題,但是由于歷史和政治的問(wèn)題,事實(shí)上存在著大量不統(tǒng)一的編碼方式,造成在信息處理過(guò)程中的信息丟失,轉(zhuǎn)換錯(cuò)誤等問(wèn)題,UCS 為問(wèn)題的解決提供了一個(gè)很好的方向,但是,在現(xiàn)在的軟件環(huán)境中,還沒(méi)有達(dá)到全面地使用。在實(shí)際中工作中應(yīng)盡量采用統(tǒng)一的編碼格式,減少編碼問(wèn)題的發(fā)生
聯(lián)系客服