前幾天看文初的《精武門之Web安全研討會(huì)首日感受》,說到利用字符集攻擊時(shí)提到以前寶寶寫的一篇有關(guān)國際化的文章,趁機(jī)再次拜讀了寶寶的這篇大作,不得不感慨寶寶的寫作功底,無敵!這么好的文章不分享出來實(shí)在是太可惜了,在此將寶寶的大作轉(zhuǎn)帖于此;
在我開發(fā)Java程序的幾年中,遇到得最多,也是別人向我提問最多的問題,就是各種各樣看似稀奇古怪的中文亂碼問題了。網(wǎng)上也有許多解釋和解決Java中文問題的文章,但水平參差不齊,有一些文章甚至是錯(cuò)誤的。
此外,我們公司自己的Java程序從一開始就采用了錯(cuò)誤的方式處理中文問題,雖能解一時(shí)之急,卻引出了越來越多的深遠(yuǎn)的問題。每當(dāng)我聽到有的同事還在討論如何特殊處理雙字節(jié)的中文GB碼,就感慨他們思路的狹隘。試問,今天我們可以用特殊的方式處理我們所熟悉的中文編碼,可是今后我們怎樣才能應(yīng)付日文版、韓文版、或世界其它國家語言的產(chǎn)品開發(fā)呢?
在我看來,與其說這些問題是“中文化問題”,不如說是“國際化問題”。所謂的“漢化”這種說法已經(jīng)隨時(shí)代遠(yuǎn)去了。想想看,這個(gè)詞帶有明顯的小農(nóng)經(jīng)濟(jì)的色彩:自家漢化自家用,哪管世界變化多。經(jīng)過漢化的軟件,常常意味著:版本落后、不兼容、不穩(wěn)定。為什么會(huì)這樣呢?根本原因是,從軟件的設(shè)計(jì)階段,就沒有考慮國際用戶的需要,沒有采用國際通用的標(biāo)準(zhǔn)。事后要彌補(bǔ)自然難上加難。
所以讓我們把眼光放開,想一想“國際化”。當(dāng)然國際化的目的還是生產(chǎn)出“漢化”的軟件,但我們可以用同樣的方法“韓化”、“日化”、“阿拉伯化”,統(tǒng)稱為“本地化” —— 這就是“國際化”的目的。國際化和本地化有兩個(gè)很體面的英文縮寫:I18n(Internationalization)和L10n(Localization)。
想要開發(fā)出國際化的軟件產(chǎn)品,首先要了解國際標(biāo)準(zhǔn),而不是使用東拼西湊的權(quán)宜之計(jì)。本文首先從相關(guān)國際標(biāo)準(zhǔn)的討論切入,相信正確地理解和應(yīng)用這些標(biāo)準(zhǔn),所有的“中文化問題”或“國際化問題”都會(huì)迎刃而解。
從學(xué)計(jì)算機(jī)的那天開始,老師就告訴我們在計(jì)算機(jī)里面,所有的英文字母都對應(yīng)到一個(gè)數(shù)字編碼,這就是ASCII碼(American Standard Code for Information Interchange)。ASCII碼是很久很久以前(1968年)制定的。它只使用了一個(gè)8位字節(jié)中的低7位,總共是127個(gè)編碼位。這樣的方案很快就不夠使用了。
在80年代早期,一些現(xiàn)在流行的標(biāo)準(zhǔn)(如ISO 8859和Unicode)還未出現(xiàn)。那時(shí)為了支持多種地區(qū)的語言,各大組織機(jī)構(gòu)或IT廠商開始發(fā)明它們自己的編碼方案,以便彌補(bǔ)ASCII編碼的不足。一時(shí)間,各種互不相容的字符編碼方案成百花齊放之勢。
為了避免混亂,ISO組織在1998年之后,陸續(xù)發(fā)表了一系列代號(hào)為8859的標(biāo)準(zhǔn),作為ASCII編碼的標(biāo)準(zhǔn)擴(kuò)展,終于統(tǒng)一了單字節(jié)的西方字符的編碼。ISO是設(shè)在瑞士的國際標(biāo)準(zhǔn)化組織的簡稱(International Organization for Standardization)。
ISO-8859-1(Latin1 - 西歐字符)
ISO-8859-1覆蓋了大多數(shù)西歐語言,包括:法國、西班牙、葡萄牙、意大利、荷蘭、德國、丹麥、瑞典、挪威、芬蘭、冰島、愛爾蘭、蘇格蘭、英格蘭等,因而也涉及到了整個(gè)美洲大陸、澳大利亞和非洲很多國家的語言。
此外,ISO-8859-1后來被采納為ISO-10646標(biāo)準(zhǔn)(后面會(huì)講到)的首頁,換句話說,Unicode的最開頭256個(gè)字符編碼和ISO-8859-1是一一對應(yīng)的。正是由于這個(gè)特殊性,使很多人產(chǎn)生了對ISO-8859-1編碼的誤用。
ISO-8859標(biāo)準(zhǔn)還包括:
但是ISO 8859系列標(biāo)準(zhǔn)的字符編碼,還是互不相容,不可能同時(shí)使用的。畢竟它們只是單字節(jié)的編碼方案。而且,它們和多字節(jié)的編碼方案如中文編碼GB2312和BIG5也是不相容的。那些歐洲字符(最高位為1的字符),在GB2312和BIG5中被認(rèn)為是雙字節(jié)漢字編碼的首字節(jié)。
單字節(jié)編碼只有256個(gè)碼位(28=256),而中文字符何止千千萬,單字節(jié)編碼不可能滿足中文編碼的需要。于是為了適應(yīng)東方文字信息處理的需要,ISO又制定了ISO 2022標(biāo)準(zhǔn)(Character code structure and extension techniques),提供了七位與八位編碼字符集的擴(kuò)充方法的標(biāo)準(zhǔn)。我國根據(jù)ISO 2022制定了國家標(biāo)準(zhǔn)GB2311 ——《信息交換用七位編碼字符集的擴(kuò)充方法》,并根據(jù)該標(biāo)準(zhǔn)制定了國家標(biāo)準(zhǔn)GB2312-80編碼。其他東方國家和地區(qū)也制定了各自的字符編碼標(biāo)準(zhǔn),如日本的JIS0208,韓國的KSC5601,臺(tái)灣地區(qū)的CNS11643等。
BIG5
BIG5是從CNS11643的早期版本發(fā)展而來的,雖然沒有包括CNS11643的全部內(nèi)容,但卻是目前臺(tái)灣、香港地區(qū)普遍使用的一種繁體漢字的市場標(biāo)準(zhǔn),包括440個(gè)符號(hào),一級(jí)漢字5401個(gè)、二級(jí)漢字7652個(gè),共計(jì)13060個(gè)漢字。
GB2312-80
全稱是《信息交換用漢字編碼字符集 基本集》,1980年發(fā)布,是中文信息處理的國家標(biāo)準(zhǔn),在大陸及海外使用簡體中文的地區(qū)(如新加坡等)是強(qiáng)制使用的唯一中文編碼。
· 雙字節(jié)編碼
· A1-A9:符號(hào)區(qū),包含682個(gè)符號(hào)
· B0-F7:漢字區(qū),包含6763個(gè)漢字
GB2312碼共收錄6763個(gè)簡體漢字、682個(gè)符號(hào),其中漢字部分:一級(jí)字3755,以拼音排序,二級(jí)字3008,以偏旁排序。該標(biāo)準(zhǔn)的制定和應(yīng)用為規(guī)范、推動(dòng)中文信息化進(jìn)程起了很大作用。
GBK
漢字內(nèi)碼擴(kuò)展規(guī)范(GBK)是國家技術(shù)監(jiān)督局1995年為中文Windows 95所制定的新的漢字內(nèi)碼規(guī)范。
· 雙字節(jié)編碼,GB2312-80的擴(kuò)充,在碼位上和GB2312-80兼容。
· 范圍:8140 ~ FEFE(剔除xx7F)共23940個(gè)碼位。
· 包含21003個(gè)漢字,包含了ISO 10646中的全部中日韓漢字,簡、繁體字融于一庫。
嚴(yán)格說,GBK不能算是國家標(biāo)準(zhǔn),最多算是一個(gè)商業(yè)標(biāo)準(zhǔn)。而GB18030才是真正的國家標(biāo)準(zhǔn)。
GB18030-2000
全稱是《信息交換用漢字編碼字符集》,是我國的強(qiáng)制標(biāo)準(zhǔn),所有不支持GB18030標(biāo)準(zhǔn)的軟件將不能作為產(chǎn)品出售。
· 單字節(jié)、雙字節(jié)、四字節(jié)編碼。
· 向下與GB2312編碼兼容。
· 支持GB 13000.1-1993中的全部中、日、韓(CJK)統(tǒng)一漢字字符和全部CJK統(tǒng)一漢字?jǐn)U展A的字符。
雖然GB18030標(biāo)準(zhǔn)非常強(qiáng)大,但它是一個(gè)中國大陸的標(biāo)準(zhǔn)。在編碼上,除了和GB2312以外,還是不能和世界上其它任何一種字符編碼統(tǒng)一。
前面所講的一切字符編碼方案,都是針對局部地區(qū)或少數(shù)語言文字的,沒有辦法同時(shí)表達(dá)所有的語言文字,或在多種語言平臺(tái)上交換。這對今天極其頻繁的國際信息交流是不相稱的。
為了提高計(jì)算機(jī)的信息處理和交換功能,使得世界各國的文字都能在計(jì)算機(jī)中處理,從1984年起,ISO組織就開始研究制定一個(gè)全新的標(biāo)準(zhǔn):通用多八位編碼字符集(Universal Multiple-Octet Coded Character Set),簡稱UCS。標(biāo)準(zhǔn)的編號(hào)為:ISO 10646。這一標(biāo)準(zhǔn)為世界各種主要語言的字符(包括簡體及繁體的中文字)及附加符號(hào),編制統(tǒng)一的內(nèi)碼。
統(tǒng)一碼(Unicode)是Universal Code的縮寫,是由另一個(gè)叫“Unicode學(xué)術(shù)學(xué)會(huì)”(The Unicode Consortium)的機(jī)構(gòu)制定的字符編碼系統(tǒng)。Unicode與ISO 10646國際編碼標(biāo)準(zhǔn)從內(nèi)容上來說是同步一致的。
Unicode是Java語言和XML的基礎(chǔ),所以我們要稍微詳細(xì)地介紹一下Unicode以及ISO 10646標(biāo)準(zhǔn)。
注意:不夠耐心的讀者可以跳過本章的余下部分。但顯然了解本章所描述的Unicode及相關(guān)編碼的技術(shù)細(xì)節(jié),有利于你更好地理解和應(yīng)用Unicode。
在1991年,Unicode學(xué)術(shù)學(xué)會(huì)與ISO國際標(biāo)準(zhǔn)化組織決定共同制訂一套適用于多種語言文本的通用編碼標(biāo)準(zhǔn)。Unicode與ISO 10646國際編碼標(biāo)準(zhǔn)于1992年1月正式合作發(fā)展一套通用編碼標(biāo)準(zhǔn)。自此,兩個(gè)組織便一直緊密合作,同步發(fā)展Unicode及ISO 10646國際編碼標(biāo)準(zhǔn)。
ISO 10646(UCS) | Unicode |
1993年,ISO組織發(fā)表ISO 10646國際編碼標(biāo)準(zhǔn)的第一個(gè)版本,全名是ISO/IEC 10646-1:1993。它收錄了20902個(gè)表意字符(ideograph,中日韓文均屬表意字符)。 | 同年,Unicode學(xué)術(shù)學(xué)會(huì)根據(jù)ISO/IEC 10646-1:1993修訂了Unicode 1.0,發(fā)布Unicode 1.1。 |
不斷改善和修訂ISO 10646標(biāo)準(zhǔn)。 | 1996年發(fā)表Unicode 2.0,1998年發(fā)表Unicode 2.1,根據(jù)ISO 10646做了一些改善和修訂,新增了歐元符號(hào)。 |
2000年10月發(fā)表了ISO 10646第二版的第一部分:ISO/IEC 10646-1:2000,新增收了6,582個(gè)表意字符于擴(kuò)展區(qū)A中(CJK Unified Ideographs Extension A)。 | 2000年2月,發(fā)表Unicode 3.0,也包含了同樣的CJK Ext A。 |
2001年,發(fā)表了ISO/IEC 10646的第二部分,增收了42711個(gè)表意字符于擴(kuò)展區(qū)B里。 | 2001年,Unicode發(fā)表3.1版,將CJK Ext B納入新版Unicode中。 |
雖然兩個(gè)組織保持如此密切的合作關(guān)系,但Unicode和ISO 10646還是有區(qū)別的。ISO 10646著重定義字符編碼,而Unicode則在此基礎(chǔ)上,為這些字符及編碼數(shù)據(jù)提出應(yīng)用的方法以及對語義數(shù)據(jù)作補(bǔ)充。
UCS的結(jié)構(gòu)是一個(gè)四維的編碼空間,每一維由一個(gè)字節(jié)(八位二進(jìn)制位)組成,范圍是00到FF??傮w上分為128個(gè)群組(Group 00-7F),每一群組由256個(gè)平面(Plane 00-FF)組成,每一平面有256行(Row 00-FF),每一行256個(gè)編碼位(Cell 00-FF)。所以,每一平面包括65,536個(gè)字符位(Character Position 0000-FFFF)。
整個(gè)編碼字符集的每個(gè)字符都由4個(gè)字節(jié),按“組-面-行-列”的順序表示。所以UCS的可編碼空間為:128 × 256 × 256 × 256 = 231。
UCS將其第一個(gè)平面(00群組中的00平面)稱作基本多語種平面(Basic Multilingual Plane,BMP)。
在UCS中,目前只有00組是重要的,Unicode學(xué)術(shù)學(xué)會(huì)斷言,在可以預(yù)見的將來,甚至不可能用完00組中的前17個(gè)平面(00平面到10平面)。因此,Unicode只定義了ISO 10646的第00組的前17個(gè)平面。事實(shí)上,目前絕大多數(shù)字符,都分配在第00平面BMP中。
下表中列出了BMP中的字符分配情況:
區(qū)間 | 描述 |
(0000-1FFF)基本拼音字符區(qū) | 包括所有拼讀文字的字母拼音和音標(biāo)。它的字符集一般較小,如:拉丁文、西里爾文、希臘文、希伯來文、阿拉伯文、泰文、天成文書(梵文)等。 |
(2000-28FF)符號(hào)區(qū) | 包括許多種用于標(biāo)點(diǎn)、數(shù)學(xué)、化學(xué)、科技及其它特殊用途上的“符號(hào)”和“丁貝符”(示意圖形符號(hào))。 |
(2E80-33FF)中日韓語音及符號(hào)區(qū) | 包括用于中國、日本、韓國語言中的標(biāo)點(diǎn)、符號(hào)、字根(筆畫)及發(fā)音等字符。 |
(3400-9FA5)中日韓漢字字符區(qū) | 由27,484個(gè)中日韓(越)的統(tǒng)一漢字組成。 |
(A000-A4C6)彝族字符區(qū) | 由1,165個(gè)中國南方彝族音節(jié)和50個(gè)其字根組成。 |
(AC00-D7A3)韓字符拼音區(qū) | 由11,172個(gè)預(yù)先組合的韓字符拼音音節(jié)組成。 |
(D800-DFFF)代理區(qū) | 這個(gè)區(qū)被平分為1024個(gè)“高半代理區(qū)”(D800-DBFF)碼位和1024個(gè)“低半代理區(qū)”(DC00-DFFF)碼位,用來形成代理對,可以得到超過一百萬個(gè)擴(kuò)充編碼位。 |
(E000-F8FF)私人專用區(qū) | 包含6,400個(gè)編碼位,用于用戶或開發(fā)商自行定義的字符編碼。 |
(F900-FA2D)兼容字符區(qū) | 包括一些被許多行業(yè)協(xié)會(huì)和國家標(biāo)準(zhǔn)廣泛使用的字符,但在Unicode編碼中有不同的表現(xiàn)形式。包含一些專用字符。 |
UCS有兩種方式來表示一個(gè)字符編碼:四字節(jié)正規(guī)形式(UCS-4,Four-octet canonical form)和雙字節(jié)基本平面形式(UCS-2,Two-octet BMP form)。
UCS-4 —— 四字節(jié)正規(guī)形式
UCS-4用4個(gè)字節(jié)來表示一個(gè)字符。第一個(gè)字節(jié)表示組(Group),第二表示平面(Plane),第三表示行(Row),第四表示單元號(hào)或列(Cell)。
UCS-2 —— 雙字節(jié)基本平面形式
當(dāng)系統(tǒng)只使用BMP的字符碼時(shí),可以省略群組和平面中的八位,將字符碼由32個(gè)位縮短為16個(gè)位(2個(gè)字節(jié))。標(biāo)記為UCS-2。
Unicode和UCS-2同樣采用16位編碼。所以一般可以把Unicode和UCS-2看作是同一樣?xùn)|西。
代理對(Surrogate Pair)
UCS-4定義了4個(gè)字節(jié)表示一個(gè)字符,用來應(yīng)付將來的擴(kuò)展是綽綽有余??墒?u>Unicode和UCS-2只定義了2個(gè)字節(jié),卻很容易用盡。代理對(Surrogate Pair)的設(shè)計(jì)在這種背景下應(yīng)運(yùn)而生。
UCS-2在BMP中開辟了一個(gè)特殊的區(qū)間(D800 - DFFF) -- 代理區(qū),并平分成兩個(gè)區(qū),分別稱為高半代理區(qū)(High-half Zone,D800 - DBFF),和低半代理區(qū)(Low-half Zone,DC00 - DFFF),各有1024個(gè)碼位。使用時(shí),從高低兩個(gè)代理區(qū)中各取一個(gè)編碼組成一個(gè)四字節(jié)的代理,來表示一個(gè)在BMP以外平面上的編碼字符位。這樣一來,總共可以多表示1024×1024個(gè)字符,映射到00群組中的01到10平面(共16個(gè)平面)。
代理對提供了用BMP的2字節(jié)編碼來表示在基本多文種平面(BMP)之外的16個(gè)平面編碼的機(jī)制。一些不常用的字符可以用代理對表示。目前,只有ISO/IEC 10646-2:2001和Unicode 3.1才使用到代理對。
高半代理區(qū)和低半代理區(qū)的劃分,使編碼位相互區(qū)分開。非代理區(qū)字符一定不會(huì)在這個(gè)區(qū)里。因?yàn)楦甙氪韰^(qū)和低半代理區(qū)不相交,所以很容易決定字符值的邊界。一個(gè)完好的文本中,高半代理碼和低半代理碼總是按先后成對出現(xiàn)。
如果在實(shí)現(xiàn)上沒有刪除代理碼或在代理碼對中插入字符,數(shù)據(jù)的完整性就可得到保證。即使數(shù)據(jù)有殘損,也只是局部的。一個(gè)殘缺的碼只影響一個(gè)字符。因?yàn)楦甙氪韰^(qū)和低半代理區(qū)不相交,且成對出現(xiàn),錯(cuò)碼不會(huì)傳到文本的其它部分。
具體來說,一個(gè)代理對(H,L)由碼值為D800-DBFF 的高半代理碼H和碼值為 DC00-DFFF低半代理碼L組成。將一個(gè)字符映射到UCS-4碼位中。假設(shè)N是UCS-4碼值,則有:(以下所有數(shù)字均為16進(jìn)制)
N = (H - D800) × 400 + (L - DC00) + 10000
于是得到N的碼值為10000到10FFFF。
注意
Unicode 3.0沒有用到代理對,直到3.1才增加了CJK Ext B,用到了02平面,需要使用代理對才能訪問。但99.99%的情況下,根本用不到那些字。此外,JDK1.4只支持到Unicode 3.0,所以目前Java還不能應(yīng)用代理對。
UTF為UCS Transformation Format的縮寫,意為“UCS轉(zhuǎn)換格式”。UCS只是一個(gè)字形和內(nèi)碼上的標(biāo)準(zhǔn),并沒有定義實(shí)際在計(jì)算機(jī)上存取的方法,而UTF便定義了一整套的計(jì)算機(jī)存取UCS編碼的轉(zhuǎn)換格式,并考慮了與其它編碼方式兼容。常用的格式有UTF-8和UTF-16。有時(shí)也用到UTF-7來進(jìn)行7位數(shù)據(jù)傳輸。
UTF-16
UTF-16是用定長16位(2字節(jié))來表示的UCS-2或Unicode轉(zhuǎn)換格式。它將Unicode的編碼值變成2字節(jié)的Big-endian(高位字節(jié)在前,低位字節(jié)在后)或Little-endian(低位字節(jié)在前,高位字節(jié)在后)編碼。UTF-16利用代理對來訪問BMP之外的字符編碼。
Java使用Big-endian系統(tǒng),而Intel系列處理器內(nèi)部使用Little-endian系統(tǒng)(學(xué)匯編語言和C語言的人都知道)。
例如:“中國”兩字,Unicode是4E2D 56FD,在Windows上用UTF-16編碼,結(jié)果為四個(gè)字節(jié):2D 4E FD 56;如果使用Java輸出,結(jié)果為:4E 2D 56 FD。
使用UTF-16有什么缺點(diǎn)呢?很顯然,
1. 所有原本1個(gè)字節(jié)就可以表示的西方字符,現(xiàn)在要用2個(gè)字節(jié)來表示,體積大了一倍。
2. 學(xué)過C的人都知道,0x00代表C字符串的結(jié)尾。但是用UTF-16來表示單字節(jié)字符(ISO-8859-1)時(shí),高位字節(jié)為0x00。這樣就會(huì)使C語言庫函數(shù)發(fā)生誤判。用UTF-16表示文件名、網(wǎng)址等,全引出無數(shù)的問題。
3. 字符的邊界不好找。程序處理時(shí)必須從字符串的頭部開始掃描,才可能正確地找出一個(gè)字符的邊界,效率較低。此外,萬一壞掉一個(gè)字節(jié),這個(gè)字節(jié)之后的字符都會(huì)錯(cuò)位,壞掉一片。
所有的這些問題,在UTF-8中都不存在。
但是,UTF-16也有其天然的優(yōu)點(diǎn):它直接表現(xiàn)了字符編碼的整數(shù)值。所以UTF-16是最直接的Unicode表示法。此外,它是定長的,這大大簡化了字符串的操作。Java語言就是用UTF-16格式將字符存儲(chǔ)在內(nèi)存中的。正是這樣,才使Java的Unicode字符串的操作格外簡單高效。
UTF-8
UTF-8使用了變長技術(shù),在每一個(gè)編碼區(qū)域有不同的字碼長度:
1. 對UCS-2,由1字節(jié)至3字節(jié)構(gòu)成;
2. 如果UCS-2使用了代理對,則UTF-8最長可到4字節(jié);
3. 對UCS-4,由1字節(jié)至6字節(jié)構(gòu)成。
因?yàn)橐宰止?jié)(8位)為組成單元,故稱為“UTF-8”。對于英文文本,UTF-8的文件大小比其它轉(zhuǎn)換格式都小。
在UTF-8內(nèi),字符由1個(gè)至6個(gè)字節(jié)為組合。下表列舉出了不同范圍的UCS碼轉(zhuǎn)換成UTF-8的規(guī)則。英文字母“x”代表可以用來記錄 Unicode 碼值的區(qū)域。
UCS-4 區(qū)域(十六進(jìn)制) | UTF-8字節(jié)組合(二進(jìn)制) |
0000 0000 —— 0000 007F | 0xxxxxxx |
0000 0080 —— 0000 07FF | 110xxxxx 10xxxxxx |
0000 0800 —— 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000 —— 001F FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
0020 0000 —— 03FF FFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
0400 0000 —— 7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
在UTF-8內(nèi),
1. 如果一個(gè)字節(jié),最高位(第8位)為0,表示這是一個(gè)ASCII字符(00 - 7F)。可見,所有ASCII編碼已經(jīng)是UTF-8了。
2. 如果一個(gè)字節(jié),以11開頭,連續(xù)的1的個(gè)數(shù)暗示這個(gè)字符的字節(jié)數(shù),例如:110xxxxx代表它是雙字節(jié)UTF-8字符的首字節(jié)。
3. 如果一個(gè)字節(jié),以10開始,表示它不是首字節(jié),需要向前查找才能得到當(dāng)前字符的首字節(jié)。
可見UTF-8可以有效地保證數(shù)據(jù)的完整性,避免出現(xiàn)編碼的錯(cuò)位。即使偶然出現(xiàn)“壞字”,也不會(huì)影響到后續(xù)的文本。
那么UTF-8有什么缺點(diǎn)呢?顯然,對于在BMP中的中文字來說,需要用3個(gè)字節(jié)才能表示,比使用UTF-16或直接使用雙字節(jié)的GB2312編碼大了0.5倍。
上文說了一大通,總結(jié)一下,其實(shí)很簡單:
聯(lián)系客服