• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      應用開發(fā)中的中文亂碼原因及其解決方案

      2012-09-21 08:31:52王天寶
      成都信息工程大學學報 2012年5期
      關鍵詞:字符集亂碼字符

      閆 靜, 王天寶, 羅 浩

      (成都信息工程學院,四川成都 610225)

      0 引言

      程序員在開發(fā)Web應用的時候經(jīng)常會遇到中文亂碼問題,雖然知道是編碼問題,改變編碼就可以解決中文亂碼問題,但是很多時候并不清楚為什么要這樣做,這一直困擾著許多開發(fā)者。所以了解字符編碼,并搞清楚中文亂碼產(chǎn)生的原因,是解決中文亂碼的最有效方法。

      1 字符編碼標準

      計算機中的信息包括數(shù)據(jù)信息和控制信息,數(shù)據(jù)信息又可分為數(shù)值和非數(shù)值信息。非數(shù)值信息和控制信息包括了字母、各種控制符號、圖形符號等,它們都以二進制編碼方式存入計算機處理,這種對字母和符號進行編碼的二進制代碼稱為字符代碼。計算機存放時不是存儲字符本身,而是存儲字符相對應的二進制表示,即每個字符在字符編碼集中的編號[1]。從字符編碼的發(fā)展歷程分析,大致可以分為3個階段:ASCII編碼、ANSI編碼、Unicode編碼。

      1.1 ASCII編碼

      美國信息互換標準代碼(American Standard Code for Information Interchange,ASCII)是基于拉丁字母的一套電腦編碼系統(tǒng)。主要用于顯示現(xiàn)代英語和其他西歐語言。是現(xiàn)今最通用的單字節(jié)編碼系統(tǒng),并等同于國際標準ISO/IEC 646。ASCII碼使用指定的7位或8位二進制數(shù)組合表示128或256種可能的字符。標準ASCII碼也叫基礎ASCII碼,使用7位二進制數(shù)表示所有的大寫和小寫字母,數(shù)字0到9、標點符號,以及在美式英語中使用的特殊控制字符[2-3]。在標準ASCII中,其最高位(b7)用作奇偶校驗位。所謂奇偶校驗,是指在代碼傳送過程中用來檢驗是否出現(xiàn)錯誤的一種方法,一般分奇校驗和偶校驗兩種。奇校驗規(guī)定:正確的代碼一個字節(jié)中1的個數(shù)必須是奇數(shù),若非奇數(shù),則在最高位b7添1;偶校驗規(guī)定:正確的代碼一個字節(jié)中1的個數(shù)必須是偶數(shù),若非偶數(shù),則在最高位b7添1。后128個稱為擴展ASCII碼,目前許多基于x86的系統(tǒng)都支持使用擴展(或“高”)ASCII。擴展ASCII碼允許將每個字符的第8位用于確定附加的128個特殊符號字符、外來語字母和圖形符號。ASCII碼在內(nèi)存中存儲字符串的方式如表1所示[4]。

      如英文字符串“GOOD”在內(nèi)存中的存儲方式為:

      表1 ASCII碼在內(nèi)存中存儲字符串的方式

      1.2 ANSI編碼

      為使計算機支持更多語言,通常使用0x80~0xFF范圍的2個字節(jié)表示1個字符。比如:漢字‘中'在中文操作系統(tǒng)中,使用[0xD6,0xD0]這兩個字節(jié)存儲。不同的國家和地區(qū)制定了不同的標準,由此產(chǎn)生了GB2312,BIG5,JIS等各自的編碼標準。使用2個字節(jié)代表一個字符的各種漢字延伸編碼方式,稱為ANSI編碼。同時為了保持與ASCII碼的兼容,約定第一個字節(jié)的最高位為0時(<128),其編碼表示與ASCII碼相同,而最高位為1時(>128),其與后面的一個字節(jié)共同表示一個擴展語言字符。按照這種定義方式不同國家和地區(qū)制定了不同的標準,由此產(chǎn)生了簡體中文GB2312、GBK、繁體中文BIG5、日文SJIS等字符集。在簡體中文系統(tǒng)下,ANSI編碼代表GB2312編碼,在日文操作系統(tǒng)下,ANSI編碼代表JIS編碼。

      不同ANSI編碼之間互不兼容,當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段ANSI編碼的文本中。這些從ASCII擴展的編碼方式,英文部分都是兼容的,但擴展部分的編碼由于采用不同的方式制定,它們是不兼容的,雖然很多字在3種體系中寫法一致(例如“中文”這兩個字),但在相應字符集中的坐標不一致,所以GB2312編碼的字符用BIG5看就全是亂碼了。另外在瀏覽其他非英語國家的頁面時(比如包含有德語的人名時)經(jīng)常出現(xiàn)奇怪的漢字,是由擴展位的編碼沖突造成。

      對于中文來說常用的是gb2312編碼,它是中華人民共和國國家漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集——基本集》,由國家標準總局發(fā)布,1981年5月1日實施,通行于大陸。新加坡等地也使用此編碼。它是計算機可以識別的編碼,適用于漢字處理、漢字通信等系統(tǒng)之間的信息交換?;炯彩杖霛h字6763個和非漢字圖形字符682個。整個字符集分成94個區(qū),每區(qū)有94個位[5]。每個區(qū)位上只有一個字符,因此可用所在的區(qū)和位來對漢字進行編碼,稱為區(qū)位碼。gb2312編碼每個漢字及符號以兩個字節(jié)表示。第一個字節(jié)稱為“高位字節(jié)”(也稱“區(qū)字節(jié))”,第二個字節(jié)稱為“低位字節(jié)”(也稱“位字節(jié)”)。“高位字節(jié)”使用了0xA1~0xF7(把01~87區(qū)的區(qū)號加上0xA0),“低位字節(jié)”使用了0xA1~0xFE(把01~94加上0xA0)。由于一級漢字從16區(qū)起始,漢字區(qū)的“高位字節(jié)”的范圍是0xB0~0xF7,“低位字節(jié)”的范圍是0xA1~0xFE,占用的碼位是72*94=6768。其中有5個空位是D7FA~D7FE。例如“啊”字在大多數(shù)程序中,會以兩個字節(jié)0xB0(第一個字節(jié))0xA1(第二個字節(jié))儲存。

      1.3 Unicode編碼

      為了使國際間信息交流更加方便,Unicode字符集編碼誕生。Unicode是Universal Multiple-Octet Coded Character Set的縮寫,中文含義是“通用多八位編碼字符集”。是由一個名為Unicode學術學會(Unicode Consortium)的機構(gòu)制訂的字符編碼系統(tǒng),Unicode目標是將世界上絕大多數(shù)國家和地區(qū)的文字、符號都編入其字符集,為每種語言中的每個字符設定了統(tǒng)一并且唯一的二進制編碼(位模式),以滿足跨語言、跨平臺進行文本轉(zhuǎn)換、處理的要求,以達到支持現(xiàn)今世界各種不同語言的書面文本的交換、處理及顯示的目的[6],使世界范圍人們通過計算機進行信息交換時達到暢通自如而無障礙。即Unicode編碼就是先將世界上存在的絕大多數(shù)常用字符納入Unicode字符集,然后進行統(tǒng)一排號。而每個Unicode字符的編碼(位模式)就是該字符在Unicode字符表中的序號,所以與上面提到的ANSI編碼不同的是,一個Unicode字符的編碼用一個整數(shù)表示,而這個整數(shù)的長度通常>=2個字節(jié)。事實證明,對可以用ASCII表示的字符使用Unicode并不高效,因為Unicode比ASCII占用大一倍的空間,而對ASCII來說高字節(jié)的0對其毫無用處。為了解決這個問題,就出現(xiàn)了一些中間格式的字符集,被稱為通用轉(zhuǎn)換格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7,UTF-7.5,UTF-8,UTF-16,以及UTF-32。目前比較常見的UTF方案有3種:

      UTF-16:其本身就是標準的Unicode編碼方案,又稱為UCS-2,固定使用16 bits(兩個字節(jié))整數(shù)表示一個字符。

      UTF-32:又稱為UCS-4,固定使用32 bits(四個字節(jié))整數(shù)表示一個字符。

      UTF-8:最廣泛使用的UTF方案,UTF-8使用可變長度字節(jié)來儲存Unicode字符,例如ASCII字母繼續(xù)使用1字節(jié)儲存,重音文字、希臘字母或西里爾字母等使用2字節(jié)來儲存,而常用的漢字就要使用3字節(jié)。輔助平面字符則使用4字節(jié)。UTF-8更便于在使用Unicode的系統(tǒng)與現(xiàn)存的單字節(jié)的系統(tǒng)進行數(shù)據(jù)傳輸和交換。與前兩個方案不同:UTF-8以字節(jié)為編碼單元,沒有字節(jié)序的問題。

      在Unicode出現(xiàn)之前,所有的字符集都是和具體編碼方案綁定在一起,都是直接將字符和最終字節(jié)流綁定,例如ASCII編碼系統(tǒng)規(guī)定使用7比特來編碼ASCII字符集;GB2312以及GBK字符集,限定了使用最多2個字節(jié)編碼所有字符,并且規(guī)定了字節(jié)序。這樣的編碼系統(tǒng)通常用簡單的查表,也就是通過代碼頁就可以直接將字符映射為存儲設備上的字節(jié)流了。這種方式的缺點在于,字符和字節(jié)流間耦合太緊密了,從而限定字符集的擴展能力。因此Unicode在設計上考慮到這一點,將字符集和字符編碼方案分離開。也就是說,雖然每個字符在Unicode字符集中都能找到唯一確定的編號(字符碼,又稱Unicode碼),但是決定最終字節(jié)流的卻是具體的字符編碼[7]。例如同樣是對Unicode字符“A”進行編碼,UTF-8字符編碼得到的字節(jié)流是0x41,而UTF-16(大端模式)得到的是0x000x41[8]。

      通過前面的介紹,了解了計算機中編碼的大致分類。在實際開發(fā)過程中,沒有必要去深究每一種編碼具體把一個字符編碼成哪幾個字節(jié),只需要知道所謂“編碼”就是把字符轉(zhuǎn)換為若干個字節(jié)的數(shù)字就可以了。

      2 中文亂碼產(chǎn)生的原因

      中文字符亂碼在Web應用開發(fā)中一直困擾著許多開發(fā)者。出現(xiàn)亂碼的原因一般是字符編碼標準不統(tǒng)一造成[5]。標準ASCII碼也叫基礎ASCII碼,使用7位二進制數(shù)表示所有的大寫和小寫字母,數(shù)字0到9、標點符號,以及在美式英語中使用的特殊控制字符。各國通過ANSI編碼擴展了適合自己國家的字符編碼標準,ANSI編碼使用2個字節(jié)表示一個字符,各種ANSI編碼是不兼容的。Unicode字符的編碼用的是一個整數(shù)表示,而這個整數(shù)的長度通常>=2個字節(jié)。因此計算機中存儲的同一組編碼采用不同的字符編碼解析就會出現(xiàn)不同的結(jié)果,就會出現(xiàn)亂碼。通過以上內(nèi)容知道產(chǎn)生字符亂碼最主要的原因就是在開發(fā)的各個環(huán)節(jié)或階段中使用的字符集不一致或者前后不兼容,從而使字符在被調(diào)用和顯示過程中不能被下一階段正確的識別,所以出現(xiàn)了亂碼[4]。

      3 解決方法

      對于Web應用解決亂碼一般從以下3方面入手,第一,首先檢查網(wǎng)頁文件本身存儲時使用的字符編碼和網(wǎng)頁聲明的字符編碼是否一致,如果不一致就會導致亂碼,那么把它改為一致就能夠解決亂碼問題了[9]。如果文件比較少,可以采用文本文檔的另存為改變文件本身存儲時使用的字符編碼,在文件比較多的情況下,可以使用轉(zhuǎn)換工具批量轉(zhuǎn)換文件本身存儲時使用的字符編碼。第二,檢查網(wǎng)頁內(nèi)是否使用META HTTP-EQUIV標簽指定了字符編碼,如果沒有為其指定合適字符編碼即可。因為如果不為其指定字符編碼,那么它會使用默認的字符編碼,此時若和文件存儲時使用的字符編碼不一致就會導致亂碼。第三,檢查服務器返回的響應頭Content-Type是否指明字符編碼 ,如果沒有為其指明正確匹配的字符編碼。

      早期字符編碼、字符集和代碼頁等概念都是表達同一個意思。例如GB2312字符集、GB2312編碼,936代碼頁,實際上表達的是同一個意思。但是對于Unicode則不同,Unicode字符集只是定義了字符的集合和唯一編號,Unicode編碼,則是對UTF-8、UTF-16等具體編碼方案的統(tǒng)稱而已,并不是具體的編碼方案。所以當需要用到字符編碼的時候,可以寫gb2312,utf-8,utf-16等,但請不要寫Unicode例如在網(wǎng)頁的meta標簽里寫charset=Unicode[7]。

      當程序使用特定字符編碼解析字節(jié)流的時候,一旦遇到無法解析的字節(jié)流時,就會用□替代。因此,一旦最終解析得到的文本包含這樣的字符,而又無法得到原始字節(jié)流的時候,說明正確的信息已經(jīng)徹底丟失了,嘗試任何字符編碼都無法從這樣的字符文本中還原出正確的信息[7]。此時要重新輸入中文信息,并使用正確的編碼才可以正確顯示。

      4 結(jié)束語

      介紹了字符編碼標準,分析了中文亂碼產(chǎn)生的主要原因,提出了解決辦法。對Web應用開發(fā)中瀏覽器端的相關中文亂碼問題分析仍然還是很有限的,另外沒有介紹服務器端中文亂碼問題。

      [1] 張峰.Java Web應用中編碼問題的研究與解決[J].計算機與網(wǎng)絡,2008,(28).

      [2] 楊玉婷.Web應用程序開發(fā)中的中文亂碼問題討論[J].重慶三峽學院學報,2011,(3):60-63.

      [3] 程曉錦.應用程序開發(fā)中的亂碼問題[J].北京印刷學院學報.2011,(8):60-62.

      [4] 高菲.Web開發(fā)中亂碼問題的開發(fā)與解決[J].科技管理研究,2010,(8):124-125.

      [5] 陳小瀚.中文編碼原理及其亂碼問題的探討[J].計算機與信息技術.2007,(24).

      [6] 蘇蘊.關于Java Web技術開發(fā)中中文亂碼問題的深入探討[J].福建電腦,2010,(8):142-143.

      [7] 關于字符編碼你所需要知道的[EB/OL].http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html

      [8] 劉財興,孫微微,肖德琴.Java編程技術中漢字“亂碼”問題的分析及解決[J].廣東交通職業(yè)技術學院學報,2002,(6):56-61.

      [9] 楊金花.JSP技術中文亂碼的原因及解決辦法[J].電子設計工程,2011,(1):25-27.

      猜你喜歡
      字符集亂碼字符
      尋找更強的字符映射管理器
      這些真的不是亂碼,是漢字
      MySQL數(shù)據(jù)庫字符集的問題研究
      字符代表幾
      一種USB接口字符液晶控制器設計
      電子制作(2019年19期)2019-11-23 08:41:50
      ORACLE字符集問題的分析
      消失的殖民村莊和神秘字符
      ORACLE數(shù)據(jù)庫字符集問題及解決方法
      醫(yī)院信息系統(tǒng)Oracle數(shù)據(jù)庫中導入數(shù)據(jù)中文亂碼的解決技術
      炫邁:用神奇亂碼勾引你視線
      商都县| 文昌市| 富宁县| 鲁甸县| 安国市| 定襄县| 丰顺县| 祁阳县| 蒙城县| 洛阳市| 慈利县| 潢川县| 柘城县| 普洱| 井陉县| 涟源市| 西贡区| 宝兴县| 依安县| 朝阳市| 卢龙县| 柳州市| 金坛市| 固阳县| 白沙| 新邵县| 太湖县| 比如县| 防城港市| 屯留县| 陵水| 会宁县| 桐柏县| 桐庐县| 建平县| 邹平县| 延安市| 漾濞| 通化市| 石首市| 信阳市|