青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

浪跡天涯

唯有努力...
努力....再努力...

gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系

最近和同事討論unicode的相關(guān)知識,同事說unicode指utf-16,和utf-8相區(qū)別;而我的理解是unicode只是一種規(guī)范,而utf-16,utf-8等都是它的具體實(shí)現(xiàn),互相也說不準(zhǔn)。于是在網(wǎng)上搜索資料,最后發(fā)現(xiàn)其實(shí)雙方都有道理,只是個人理解不一樣罷了,的確通常來說的unicode是指utf-16的實(shí)現(xiàn)方式。這下面是搜索到的資料:

以前收藏的一篇

標(biāo)題 談?wù)刄nicode編碼,簡要解釋UCS、UTF、BMP、BOM等名詞 選擇自 fmddlmyy 的 Blog
關(guān)鍵字 談?wù)刄nicode編碼,簡要解釋UCS、UTF、BMP、BOM等名詞

這是一篇程序員寫給程序員的趣味讀物。所謂趣味是指可以比較輕松地了解一些原來不清楚的概念,增進(jìn)知識,類似于打RPG游戲的升級。整理這篇文章的動機(jī)是兩個問題:

問題一:
使用Windows記事本的“另存為”,可以在GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉(zhuǎn)換。同樣是txt文件,Windows是怎樣識別編碼方式的呢?

我很早前就發(fā)現(xiàn)Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字節(jié),分別是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但這些標(biāo)記是基于什么標(biāo)準(zhǔn)呢?

問題二:
最近在網(wǎng)上看到一個ConvertUTF.c,實(shí)現(xiàn)了UTF-32、UTF-16和UTF-8這三種編碼方式的相互轉(zhuǎn)換。對于Unicode(UCS2)、GBK、UTF-8這些編碼方式,我原來就了解。但這個程序讓我有些糊涂,想不起來UTF-16和UCS2有什么關(guān)系。
查了查相關(guān)資料,總算將這些問題弄清楚了,順帶也了解了一些Unicode的細(xì)節(jié)。寫成一篇文章,送給有過類似疑問的朋友。本文在寫作時盡量做到通俗易懂,但要求讀者知道什么是字節(jié),什么是十六進(jìn)制。

0、big endian和little endian
big endian和little endian是CPU處理多字節(jié)數(shù)的不同方式。例如“漢”字的Unicode編碼是6C49。那么寫到文件里時,究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。

“endian”這個詞出自《格列佛游記》。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發(fā)生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。

我們一般將endian翻譯成“字節(jié)序”,將big endian和little endian稱作“大尾”和“小尾”。

1、字符編碼、內(nèi)碼,順帶介紹漢字編碼
字符必須編碼后才能被計(jì)算機(jī)處理。計(jì)算機(jī)使用的缺省編碼方式就是計(jì)算機(jī)的內(nèi)碼。早期的計(jì)算機(jī)使用7位的ASCII編碼,為了處理漢字,程序員設(shè)計(jì)了用于簡體中文的GB2312和用于繁體中文的big5。

GB2312(1980年)一共收錄了7445個字符,包括6763個漢字和682個其它符號。漢字區(qū)的內(nèi)碼范圍高字節(jié)從B0-F7,低字節(jié)從A1-FE,占用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。

GB2312支持的漢字太少。1995年的漢字?jǐn)U展規(guī)范GBK1.0收錄了21886個符號,它分為漢字區(qū)和圖形符號區(qū)。漢字區(qū)包括21003個字符。2000年的GB18030是取代GBK1.0的正式國家標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數(shù)民族文字?,F(xiàn)在的PC平臺必須支持GB18030,對嵌入式產(chǎn)品暫不作要求。所以手機(jī)、MP3一般只支持GB2312。

從ASCII、GB2312、GBK到GB18030,這些編碼方法是向下兼容的,即同一個字符在這些方案中總是有相同的編碼,后面的標(biāo)準(zhǔn)支持更多的字符。在這些編碼中,英文和中文可以統(tǒng)一地處理。區(qū)分中文編碼的方法是高字節(jié)的最高位不為0。按照程序員的稱呼,GB2312、GBK到GB18030都屬于雙字節(jié)字符集 (DBCS)。

有的中文Windows的缺省內(nèi)碼還是GBK,可以通過GB18030升級包升級到GB18030。不過GB18030相對GBK增加的字符,普通人是很難用到的,通常我們還是用GBK指代中文Windows內(nèi)碼。

這里還有一些細(xì)節(jié):

GB2312的原文還是區(qū)位碼,從區(qū)位碼到內(nèi)碼,需要在高字節(jié)和低字節(jié)上分別加上A0。

在DBCS中,GB內(nèi)碼的存儲格式始終是big endian,即高位在前。

GB2312的兩個字節(jié)的最高位都是1。但符合這個條件的碼位只有128*128=16384個。所以GBK和GB18030的低字節(jié)最高位都可能不是1。不過這不影響DBCS字符流的解析:在讀取DBCS字符流時,只要遇到高位為1的字節(jié),就可以將下兩個字節(jié)作為一個雙字節(jié)編碼,而不用管低字節(jié)的高位是什么。

2、Unicode、UCS和UTF
前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準(zhǔn)確地說,是與ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

Unicode也是一種字符編碼方法,不過它是由國際組織設(shè)計(jì),可以容納全世界所有語言文字的編碼方案。Unicode的學(xué)名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。

根據(jù)維基百科全書(http://zh.wikipedia.org/wiki/)的記載:歷史上存在兩個試圖獨(dú)立設(shè)計(jì)Unicode的組織,即國際標(biāo)準(zhǔn)化組織(ISO)和一個軟件制造商的協(xié)會(unicode.org)。ISO開發(fā)了ISO 10646項(xiàng)目,Unicode協(xié)會開發(fā)了Unicode項(xiàng)目。

在1991年前后,雙方都認(rèn)識到世界不需要兩個不兼容的字符集。于是它們開始合并雙方的工作成果,并為創(chuàng)立一個單一編碼表而協(xié)同工作。從Unicode2.0開始,Unicode項(xiàng)目采用了與ISO 10646-1相同的字庫和字碼。

目前兩個項(xiàng)目仍都存在,并獨(dú)立地公布各自的標(biāo)準(zhǔn)。Unicode協(xié)會現(xiàn)在的最新版本是2005年的Unicode 4.1.0。ISO的最新標(biāo)準(zhǔn)是10646-3:2003。

UCS規(guī)定了怎么用多個字節(jié)表示各種文字。怎樣傳輸這些編碼,是由UTF(UCS Transformation Format)規(guī)范規(guī)定的,常見的UTF規(guī)范包括UTF-8、UTF-7、UTF-16。

IETF的RFC2781和RFC3629以RFC的一貫風(fēng)格,清晰、明快又不失嚴(yán)謹(jǐn)?shù)孛枋隽薝TF-16和UTF-8的編碼方法。我總是記不得IETF是Internet Engineering Task Force的縮寫。但I(xiàn)ETF負(fù)責(zé)維護(hù)的RFC是Internet上一切規(guī)范的基礎(chǔ)。

3、UCS-2、UCS-4、BMP

UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個字節(jié)編碼,UCS-4就是用4個字節(jié)(實(shí)際上只用了31位,最高位必須為0)編碼。下面讓我們做一些簡單的數(shù)學(xué)游戲:

UCS-2有2^16=65536個碼位,UCS-4有2^31=2147483648個碼位。

UCS-4根據(jù)最高位為0的最高字節(jié)分成2^7=128個group。每個group再根據(jù)次高字節(jié)分為256個plane。每個plane根據(jù)第3個字節(jié)分為256行 (rows),每行包含256個cells。當(dāng)然同一行的cells只是最后一個字節(jié)不同,其余都相同。

group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中,高兩個字節(jié)為0的碼位被稱作BMP。

將UCS-4的BMP去掉前面的兩個零字節(jié)就得到了UCS-2。在UCS-2的兩個字節(jié)前加上兩個零字節(jié),就得到了UCS-4的BMP。而目前的UCS-4規(guī)范中還沒有任何字符被分配在BMP之外。

4、UTF編碼

UTF-8就是以8位為單元對UCS進(jìn)行編碼。從UCS-2到UTF-8的編碼方式如下:

UCS-2編碼(16進(jìn)制) UTF-8 字節(jié)流(二進(jìn)制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

例如“漢”字的Unicode編碼是6C49。6C49在0800-FFFF之間,所以肯定要用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx。將6C49寫成二進(jìn)制是:0110 110001 001001, 用這個比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

讀者可以用記事本測試一下我們的編碼是否正確。

UTF-16以16位為單元對UCS進(jìn)行編碼。對于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼對應(yīng)的16位無符號整數(shù)。對于不小于0x10000的UCS碼,定義了一個算法。不過由于實(shí)際使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以認(rèn)為UTF-16和UCS-2基本相同。但UCS-2只是一個編碼方案,UTF-16卻要用于實(shí)際的傳輸,所以就不得不考慮字節(jié)序的問題。

5、UTF的字節(jié)序和BOM
UTF-8以字節(jié)為編碼單元,沒有字節(jié)序的問題。UTF-16以兩個字節(jié)為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字節(jié)序。例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節(jié)流“594E”,那么這是“奎”還是“乙”?

Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點(diǎn)小聰明的想法:

在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中。UCS規(guī)范建議我們在傳輸字節(jié)流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。

這樣如果接收者收到FEFF,就表明這個字節(jié)流是Big-Endian的;如果收到FFFE,就表明這個字節(jié)流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。

UTF-8不需要BOM來表明字節(jié)順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗(yàn)證一下)。所以如果接收者收到以EF BB BF開頭的字節(jié)流,就知道這是UTF-8編碼了。

Windows就是使用BOM來標(biāo)記文本文件的編碼方式的。

6、進(jìn)一步的參考資料
本文主要參考的資料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

我還找了兩篇看上去不錯的資料,不過因?yàn)槲议_始的疑問都找到了答案,所以就沒有看:

"Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
"Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)
我寫過UTF-8、UCS-2、GBK相互轉(zhuǎn)換的軟件包,包括使用Windows API和不使用Windows API的版本。以后有時間的話,我會整理一下放到我的個人主頁上(http://fmddlmyy.home4u.china.com/)。



Unicode,GBK,GB2312,UTF-8概念基礎(chǔ)
本部分采用重用,轉(zhuǎn)載一篇文章來完成這部分的目標(biāo)。
來源:holen'blog   對字符編碼與Unicode,ISO 10646,UCS,UTF8,UTF16,GBK,GB2312的理解
地址:http://blog.donews.com/holen/archive/2004/11/30/188182.aspx
 
Unicode:

unicode.org制定的編碼機(jī)制, 要將全世界常用文字都函括進(jìn)去.
在1.0中是16位編碼, 由U+0000到U+FFFF. 每個2byte碼對應(yīng)一個字符; 在2.0開始拋棄了16位限制, 原來的16位作為基本位平面, 另外增加了16個位平面, 相當(dāng)于20位編碼, 編碼范圍0到0x10FFFF.

UCS:

ISO制定的ISO10646標(biāo)準(zhǔn)所定義的 Universal Character Set, 采用4byte編碼.

Unicode與UCS的關(guān)系:

ISO與unicode.org是兩個不同的組織, 因此最初制定了不同的標(biāo)準(zhǔn); 但自從unicode2.0開始, unicode采用了與ISO 10646-1相同的字庫和字碼, ISO也承諾ISO10646將不會給超出0x10FFFF的UCS-4編碼賦值, 使得兩者保持一致.

UCS的編碼方式:

  • UCS-2, 與unicode的2byte編碼基本一樣.
  • UCS-4, 4byte編碼, 目前是在UCS-2前加上2個全零的byte.

    UTF: Unicode/UCS Transformation Format
  • UTF-8, 8bit編碼, ASCII不作變換, 其他字符做變長編碼, 每個字符1-3 byte. 通常作為外碼. 有以下優(yōu)點(diǎn):
    * 與CPU字節(jié)順序無關(guān), 可以在不同平臺之間交流
    * 容錯能力高, 任何一個字節(jié)損壞后, 最多只會導(dǎo)致一個編碼碼位損失, 不會鏈鎖錯誤(如GB碼錯一個字節(jié)就會整行亂碼)
  • UTF-16, 16bit編碼, 是變長碼, 大致相當(dāng)于20位編碼, 值在0到0x10FFFF之間, 基本上就是unicode編碼的實(shí)現(xiàn). 它是變長碼, 與CPU字序有關(guān), 但因?yàn)樽钍】臻g, 常作為網(wǎng)絡(luò)傳輸?shù)耐獯a.
    UTF-16是unicode的preferred encoding.
  • UTF-32, 僅使用了unicode范圍(0到0x10FFFF)的32位編碼, 相當(dāng)于UCS-4的子集.

    UTF與unicode的關(guān)系:

    Unicode是一個字符集, 可以看作為內(nèi)碼.
    而UTF是一種編碼方式, 它的出現(xiàn)是因?yàn)閡nicode不適宜在某些場合直接傳輸和處理. UTF-16直接就是unicode編碼, 沒有變換, 但它包含了0x00在編碼內(nèi), 頭256字節(jié)碼的第一個byte都是0x00, 在操作系統(tǒng)(C語言)中有特殊意義, 會引起問題. 采用UTF-8編碼對unicode的直接編碼作些變換可以避免這問題, 并帶來一些優(yōu)點(diǎn).

    中國國標(biāo)編碼:
  • GB 13000: 完全等同于ISO 10646-1/Unicode 2.1, 今后也將隨ISO 10646/Unicode的標(biāo)準(zhǔn)更改而同步更改.
  • GBK: 對GB2312的擴(kuò)充, 以容納GB2312字符集范圍以外的Unicode 2.1的統(tǒng)一漢字部分, 并且增加了部分unicode中沒有的字符.
  • GB 18030-2000: 基于GB 13000, 作為Unicode 3.0的GBK擴(kuò)展版本, 覆蓋了所有unicode編碼, 地位等同于UTF-8, UTF-16, 是一種unicode編碼形式. 變長編碼, 用單字節(jié)/雙字節(jié)/4字節(jié)對字符編碼. GB18030向下兼容GB2312/GBK.
    GB 18030是中國所有非手持/嵌入式計(jì)算機(jī)系統(tǒng)的強(qiáng)制實(shí)施標(biāo)準(zhǔn).


    -------------------------------


     

    什么是 UCS 和 ISO 10646?

    國際標(biāo)準(zhǔn) ISO 10646 定義了 通用字符集 (Universal Character Set, UCS). UCS 是所有其他字符集標(biāo)準(zhǔn)的一個超集. 它保證與其他字符集是雙向兼容的. 就是說, 如果你將任何文本字符串翻譯到 UCS格式, 然后再翻譯回原編碼, 你不會丟失任何信息.

    UCS 包含了用于表達(dá)所有已知語言的字符. 不僅包括拉丁語,希臘語, 斯拉夫語,希伯來語,阿拉伯語,亞美尼亞語和喬治亞語的描述, 還包括中文, 日文和韓文這樣的象形文字, 以及 平假名, 片假名, 孟加拉語, 旁遮普語果魯穆奇字符(Gurmukhi), 泰米爾語, 印.埃納德語(Kannada), Malayalam, 泰國語, 老撾語, 漢語拼音(Bopomofo), Hangul, Devangari, Gujarati, Oriya, Telugu 以及其他數(shù)也數(shù)不清的語. 對于還沒有加入的語言, 由于正在研究怎樣在計(jì)算機(jī)中最好地編碼它們, 因而最終它們都將被加入. 這些語言包括 Tibetian, 高棉語, Runic(古代北歐文字), 埃塞俄比亞語, 其他象形文字, 以及各種各樣的印-歐語系的語言, 還包括挑選出來的藝術(shù)語言比如 Tengwar, Cirth 和 克林貢語(Klingon). UCS 還包括大量的圖形的, 印刷用的, 數(shù)學(xué)用的和科學(xué)用的符號, 包括所有由 TeX, Postscript, MS-DOS,MS-Windows, Macintosh, OCR 字體, 以及許多其他字處理和出版系統(tǒng)提供的字符.

    ISO 10646 定義了一個 31 位的字符集. 然而, 在這巨大的編碼空間中, 迄今為止只分配了前 65534 個碼位 (0x0000 到 0xFFFD). 這個 UCS 的 16位子集稱為 基本多語言面 (Basic Multilingual Plane, BMP). 將被編碼在 16 位 BMP 以外的字符都屬于非常特殊的字符(比如象形文字), 且只有專家在歷史和科學(xué)領(lǐng)域里才會用到它們. 按當(dāng)前的計(jì)劃, 將來也許再也不會有字符被分配到從 0x000000 到 0x10FFFF 這個覆蓋了超過 100 萬個潛在的未來字符的 21 位的編碼空間以外去了. ISO 10646-1 標(biāo)準(zhǔn)第一次發(fā)表于 1993 年, 定義了字符集與 BMP 中內(nèi)容的架構(gòu). 定義 BMP 以外的字符編碼的第二部分 ISO 10646-2 正在準(zhǔn)備中, 但也許要過好幾年才能完成. 新的字符仍源源不斷地加入到 BMP 中, 但已經(jīng)存在的字符是穩(wěn)定的且不會再改變了.

    UCS 不僅給每個字符分配一個代碼, 而且賦予了一個正式的名字. 表示一個 UCS 或 Unicode 值的十六進(jìn)制數(shù), 通常在前面加上 "U+", 就象 U+0041 代表字符"拉丁大寫字母A". UCS 字符 U+0000 到 U+007F 與 US-ASCII(ISO 646) 是一致的, U+0000 到 U+00FF 與 ISO 8859-1(Latin-1) 也是一致的. 從 U+E000 到 U+F8FF, 已經(jīng) BMP 以外的大范圍的編碼是為私用保留的.

    什么是組合字符?

    UCS里有些編碼點(diǎn)分配給了 組合字符.它們類似于打字機(jī)上的無間隔重音鍵. 單個的組合字符不是一個完整的字符. 它是一個類似于重音符或其他指示標(biāo)記, 加在前一個字符后面. 因而, 重音符可以加在任何字符后面. 那些最重要的被加重的字符, 就象普通語言的正字法(orthographies of common languages)里用到的那種, 在 UCS 里都有自己的位置, 以確保同老的字符集的向后兼容性. 既有自己的編碼位置, 又可以表示為一個普通字符跟隨一個組合字符的被加重字符, 被稱為 預(yù)作字符(precomposed characters). UCS 里的預(yù)作字符是為了同沒有預(yù)作字符的舊編碼, 比如 ISO 8859, 保持向后兼容性而設(shè)的. 組合字符機(jī)制允許在任何字符后加上重音符或其他指示標(biāo)記, 這在科學(xué)符號中特別有用, 比如數(shù)學(xué)方程式和國際音標(biāo)字母, 可能會需要在一個基本字符后組合上一個或多個指示標(biāo)記.

    組合字符跟隨著被修飾的字符. 比如, 德語中的元音變音字符 ("拉丁大寫字母A 加上分音符"), 既可以表示為 UCS 碼 U+00C4 的預(yù)作字符, 也可以表示成一個普通 "拉丁大寫字母A" 跟著一個"組合分音符":U+0041 U+0308 這樣的組合. 當(dāng)需要堆疊多個重音符, 或在一個基本字符的上面和下面都要加上組合標(biāo)記時, 可以使用多個組合字符. 比如在泰國文中, 一個基本字符最多可加上兩個組合字符.

    什么是 UCS 實(shí)現(xiàn)級別?

    不是所有的系統(tǒng)都需要支持象組合字符這樣的 UCS 里所有的先進(jìn)機(jī)制. 因此 ISO 10646 指定了下列三種實(shí)現(xiàn)級別:

    級別1
    不支持組合字符和 Hangul Jamo 字符 (一種特別的, 更加復(fù)雜的韓國文的編碼, 使用兩個或三個子字符來編碼一個韓文音節(jié))
    級別2
    類似于級別1, 但在某些文字中, 允許一列固定的組合字符 (例如, 希伯來文, 阿拉伯文, Devangari, 孟加拉語, 果魯穆奇語, Gujarati, Oriya, 泰米爾語, Telugo, 印.埃納德語, Malayalam, 泰國語和老撾語). 如果沒有這最起碼的幾個組合字符, UCS 就不能完整地表達(dá)這些語言.
    級別3
    支持所有的 UCS 字符, 例如數(shù)學(xué)家可以在任意一個字符上加上一個 tilde(顎化符號,西班牙語字母上面的~)或一個箭頭(或兩者都加).

    什么是 Unicode?

    歷史上, 有兩個獨(dú)立的, 創(chuàng)立單一字符集的嘗試. 一個是國際標(biāo)準(zhǔn)化組織(ISO)的 ISO 10646 項(xiàng)目, 另一個是由(一開始大多是美國的)多語言軟件制造商組成的協(xié)會組織的 Unicode 項(xiàng)目. 幸運(yùn)的是, 1991年前后, 兩個項(xiàng)目的參與者都認(rèn)識到, 世界不需要兩個不同的單一字符集. 它們合并雙方的工作成果, 并為創(chuàng)立一個單一編碼表而協(xié)同工作. 兩個項(xiàng)目仍都存在并獨(dú)立地公布各自的標(biāo)準(zhǔn), 但 Unicode 協(xié)會和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 標(biāo)準(zhǔn)的碼表兼容, 并緊密地共同調(diào)整任何未來的擴(kuò)展.

    那么 Unicode 和 ISO 10646 不同在什么地方?

    Unicode 協(xié)會公布的 Unicode 標(biāo)準(zhǔn) 嚴(yán)密地包含了 ISO 10646-1 實(shí)現(xiàn)級別3的基本多語言面. 在兩個標(biāo)準(zhǔn)里所有的字符都在相同的位置并且有相同的名字.

    Unicode 標(biāo)準(zhǔn)額外定義了許多與字符有關(guān)的語義符號學(xué), 一般而言是對于實(shí)現(xiàn)高質(zhì)量的印刷出版系統(tǒng)的更好的參考. Unicode 詳細(xì)說明了繪制某些語言(比如阿拉伯語)表達(dá)形式的算法, 處理雙向文字(比如拉丁與希伯來文混合文字)的算法和 排序與字符串比較 所需的算法, 以及其他許多東西.

    另一方面, ISO 10646 標(biāo)準(zhǔn), 就象廣為人知的 ISO 8859 標(biāo)準(zhǔn)一樣, 只不過是一個簡單的字符集表. 它指定了一些與標(biāo)準(zhǔn)有關(guān)的術(shù)語, 定義了一些編碼的別名, 并包括了規(guī)范說明, 指定了怎樣使用 UCS 連接其他 ISO 標(biāo)準(zhǔn)的實(shí)現(xiàn), 比如 ISO 6429 和 ISO 2022. 還有一些與 ISO 緊密相關(guān)的, 比如 ISO 14651 是關(guān)于 UCS 字符串排序的.

    考慮到 Unicode 標(biāo)準(zhǔn)有一個易記的名字, 且在任何好的書店里的 Addison-Wesley 里有, 只花費(fèi) ISO 版本的一小部分, 且包括更多的輔助信息, 因而它成為使用廣泛得多的參考也就不足為奇了. 然而, 一般認(rèn)為, 用于打印 ISO 10646-1 標(biāo)準(zhǔn)的字體在某些方面的質(zhì)量要高于用于打印 Unicode 2.0的. 專業(yè)字體設(shè)計(jì)者總是被建議說要兩個標(biāo)準(zhǔn)都實(shí)現(xiàn), 但一些提供的樣例字形有顯著的區(qū)別. ISO 10646-1 標(biāo)準(zhǔn)同樣使用四種不同的風(fēng)格變體來顯示表意文字如中文, 日文和韓文 (CJK), 而 Unicode 2.0 的表里只有中文的變體. 這導(dǎo)致了普遍的認(rèn)為 Unicode 對日本用戶來說是不可接收的傳說, 盡管是錯誤的.

    什么是 UTF-8?

    首先 UCS 和 Unicode 只是分配整數(shù)給字符的編碼表. 現(xiàn)在存在好幾種將一串字符表示為一串字節(jié)的方法. 最顯而易見的兩種方法是將 Unicode 文本存儲為 2 個 或 4 個字節(jié)序列的串. 這兩種方法的正式名稱分別為 UCS-2 和 UCS-4. 除非另外指定, 否則大多數(shù)的字節(jié)都是這樣的(Bigendian convention). 將一個 ASCII 或 Latin-1 的文件轉(zhuǎn)換成 UCS-2 只需簡單地在每個 ASCII 字節(jié)前插入 0x00. 如果要轉(zhuǎn)換成 UCS-4, 則必須在每個 ASCII 字節(jié)前插入三個 0x00.

    在 Unix 下使用 UCS-2 (或 UCS-4) 會導(dǎo)致非常嚴(yán)重的問題. 用這些編碼的字符串會包含一些特殊的字符, 比如 '\0' 或 '/', 它們在 文件名和其他 C 庫函數(shù)參數(shù)里都有特別的含義. 另外, 大多數(shù)使用 ASCII 文件的 UNIX 下的工具, 如果不進(jìn)行重大修改是無法讀取 16 位的字符的. 基于這些原因, 在文件名, 文本文件, 環(huán)境變量等地方, UCS-2 不適合作為 Unicode 的外部編碼.

    在 ISO 10646-1 Annex RRFC 2279 里定義的 UTF-8 編碼沒有這些問題. 它是在 Unix 風(fēng)格的操作系統(tǒng)下使用 Unicode 的明顯的方法.

    UTF-8 有一下特性:

    • UCS 字符 U+0000 到 U+007F (ASCII) 被編碼為字節(jié) 0x00 到 0x7F (ASCII 兼容). 這意味著只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 兩種編碼方式下是一樣的.
    • 所有 >U+007F 的 UCS 字符被編碼為一個多個字節(jié)的串, 每個字節(jié)都有標(biāo)記位集. 因此, ASCII 字節(jié) (0x00-0x7F) 不可能作為任何其他字符的一部分.
    • 表示非 ASCII 字符的多字節(jié)串的第一個字節(jié)總是在 0xC0 到 0xFD 的范圍里, 并指出這個字符包含多少個字節(jié). 多字節(jié)串的其余字節(jié)都在 0x80 到 0xBF 范圍里. 這使得重新同步非常容易, 并使編碼無國界, 且很少受丟失字節(jié)的影響.
    • 可以編入所有可能的 231個 UCS 代碼
    • UTF-8 編碼字符理論上可以最多到 6 個字節(jié)長, 然而 16 位 BMP 字符最多只用到 3 字節(jié)長.
    • Bigendian UCS-4 字節(jié)串的排列順序是預(yù)定的.
    • 字節(jié) 0xFE 和 0xFF 在 UTF-8 編碼中從未用到.

    下列字節(jié)串用來表示一個字符. 用到哪個串取決于該字符在 Unicode 中的序號.

    U-00000000 - U-0000007F: 0xxxxxxx
    U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
    U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
    U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

    xxx 的位置由字符編碼數(shù)的二進(jìn)制表示的位填入. 越靠右的 x 具有越少的特殊意義. 只用最短的那個足夠表達(dá)一個字符編碼數(shù)的多字節(jié)串. 注意在多字節(jié)串中, 第一個字節(jié)的開頭"1"的數(shù)目就是整個串中字節(jié)的數(shù)目.

    例如: Unicode 字符 U+00A9 = 1010 1001 (版權(quán)符號) 在 UTF-8 里的編碼為:

    11000010 10101001 = 0xC2 0xA9

    而字符 U+2260 = 0010 0010 0110 0000 (不等于) 編碼為:

    11100010 10001001 10100000 = 0xE2 0x89 0xA0

    這種編碼的官方名字拼寫為 UTF-8, 其中 UTF 代表 UCS Transformation Format. 請勿在任何文檔中用其他名字 (比如 utf8 或 UTF_8) 來表示 UTF-8, 當(dāng)然除非你指的是一個變量名而不是這種編碼本身.

    什么編程語言支持 Unicode?

    在大約 1993 年之后開發(fā)的大多數(shù)現(xiàn)代編程語言都有一個特別的數(shù)據(jù)類型, 叫做 Unicode/ISO 10646-1 字符. 在 Ada95 中叫 Wide_Character, 在 Java 中叫 char.

    ISO C 也詳細(xì)說明了處理多字節(jié)編碼和寬字符 (wide characters) 的機(jī)制, 1994 年 9 月 Amendment 1 to ISO C 發(fā)表時又加入了更多. 這些機(jī)制主要是為各類東亞編碼而設(shè)計(jì)的, 它們比處理 UCS 所需的要健壯得多. UTF-8 是 ISO C 標(biāo)準(zhǔn)調(diào)用多字節(jié)字符串的編碼的一個例子, wchar_t 類型可以用來存放 Unicode 字符.


    附錄1 再說說區(qū)位碼、GB2312、內(nèi)碼和代碼頁
    有的朋友對文章中這句話還有疑問:
    “GB2312的原文還是區(qū)位碼,從區(qū)位碼到內(nèi)碼,需要在高字節(jié)和低字節(jié)上分別加上A0。”

    我再詳細(xì)解釋一下:

    “GB2312的原文”是指國家1980年的一個標(biāo)準(zhǔn)《中華人民共和國國家標(biāo)準(zhǔn) 信息交換用漢字編碼字符集 基本集 GB 2312-80》。這個標(biāo)準(zhǔn)用兩個數(shù)來編碼漢字和中文符號。第一個數(shù)稱為“區(qū)”,第二個數(shù)稱為“位”。所以也稱為區(qū)位碼。1-9區(qū)是中文符號,16-55區(qū)是一級漢字,56-87區(qū)是二級漢字?,F(xiàn)在Windows也還有區(qū)位輸入法,例如輸入1601得到“啊”。(這個區(qū)位輸入法可以自動識別16進(jìn)制的GB2312和10進(jìn)制的區(qū)位碼,也就是說輸入B0A1同樣會得到“啊”。)

    內(nèi)碼是指操作系統(tǒng)內(nèi)部的字符編碼。早期操作系統(tǒng)的內(nèi)碼是與語言相關(guān)的?,F(xiàn)在的Windows在系統(tǒng)內(nèi)部支持Unicode,然后用代碼頁適應(yīng)各種語言,“內(nèi)碼”的概念就比較模糊了。微軟一般將缺省代碼頁指定的編碼說成是內(nèi)碼。

    內(nèi)碼這個詞匯,并沒有什么官方的定義,代碼頁也只是微軟這個公司的叫法。作為程序員,我們只要知道它們是什么東西,沒有必要過多地考證這些名詞。

    所謂代碼頁(code page)就是針對一種語言文字的字符編碼。例如GBK的code page是CP936,BIG5的code page是CP950,GB2312的code page是CP20936。

    Windows中有缺省代碼頁的概念,即缺省用什么編碼來解釋字符。例如Windows的記事本打開了一個文本文件,里面的內(nèi)容是字節(jié)流:BA、BA、D7、D6。Windows應(yīng)該去怎么解釋它呢?

    是按照Unicode編碼解釋、還是按照GBK解釋、還是按照BIG5解釋,還是按照ISO8859-1去解釋?如果按GBK去解釋,就會得到“漢字”兩個字。按照其它編碼解釋,可能找不到對應(yīng)的字符,也可能找到錯誤的字符。所謂“錯誤”是指與文本作者的本意不符,這時就產(chǎn)生了亂碼。

    答案是Windows按照當(dāng)前的缺省代碼頁去解釋文本文件里的字節(jié)流。缺省代碼頁可以通過控制面板的區(qū)域選項(xiàng)設(shè)置。記事本的另存為中有一項(xiàng)ANSI,其實(shí)就是按照缺省代碼頁的編碼方法保存。

    Windows的內(nèi)碼是Unicode,它在技術(shù)上可以同時支持多個代碼頁。只要文件能說明自己使用什么編碼,用戶又安裝了對應(yīng)的代碼頁,Windows就能正確顯示,例如在HTML文件中就可以指定charset。

    有的HTML文件作者,特別是英文作者,認(rèn)為世界上所有人都使用英文,在文件中不指定charset。如果他使用了0x80-0xff之間的字符,中文Windows又按照缺省的GBK去解釋,就會出現(xiàn)亂碼。這時只要在這個html文件中加上指定charset的語句,例如:
    <meta http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
    如果原作者使用的代碼頁和ISO8859-1兼容,就不會出現(xiàn)亂碼了。

    再說區(qū)位碼,啊的區(qū)位碼是1601,寫成16進(jìn)制是0x10,0x01。這和計(jì)算機(jī)廣泛使用的ASCII編碼沖突。為了兼容00-7f的ASCII編碼,我們在區(qū)位碼的高、低字節(jié)上分別加上A0。這樣“啊”的編碼就成為B0A1。我們將加過兩個A0的編碼也稱為GB2312編碼,雖然GB2312的原文根本沒提到這一點(diǎn)。


    字符編碼筆記:ASCII,Unicode和UTF-8


     

    今天中午,我突然想搞清楚Unicode和UTF-8之間的關(guān)系,于是就開始在網(wǎng)上查資料。

    結(jié)果,這個問題比我想象的復(fù)雜,從午飯后一直看到晚上9點(diǎn),才算初步搞清楚。

    下面就是我的筆記,主要用來整理自己的思路。但是,我盡量試圖寫得通俗易懂,希望能對其他朋友有用。畢竟,字符編碼是計(jì)算機(jī)技術(shù)的基石,想要熟練使用計(jì)算機(jī),就必須懂得一點(diǎn)字符編碼的知識。

    1. ASCII碼

    我們知道,在計(jì)算機(jī)內(nèi)部,所有的信息最終都表示為一個二進(jìn)制的字符串。每一個二進(jìn)制位(bit)有0和1兩種狀態(tài),因此八個二進(jìn)制位就可以組合出256種狀態(tài),這被稱為一個字節(jié)(byte)。也就是說,一個字節(jié)一共可以用來表示256種不同的狀態(tài),每一個狀態(tài)對應(yīng)一個符號,就是256個符號,從0000000到11111111。

    上個世紀(jì)60年代,美國制定了一套字符編碼,對英語字符與二進(jìn)制位之間的關(guān)系,做了統(tǒng)一規(guī)定。這被稱為ASCII碼,一直沿用至今。

    ASCII碼一共規(guī)定了128個字符的編碼,比如空格“SPACE”是32(二進(jìn)制00100000),大寫的字母A是65(二進(jìn)制01000001)。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0。

    2、非ASCII編碼

    英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。比如,在法語中,字母上方有注音符號,它就無法用ASCII碼表示。于是,一些歐洲國家就決定,利用字節(jié)中閑置的最高位編入新的符號。比如,法語中的é的編碼為130(二進(jìn)制10000010)。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多256個符號。

    但是,這里又出現(xiàn)了新的問題。不同的國家有不同的字母,因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (?),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有這些編碼方式中,0—127表示的符號是一樣的,不一樣的只是128—255的這一段。

    至于亞洲國家的文字,使用的符號就更多了,漢字就多達(dá)10萬左右。一個字節(jié)只能表示256種符號,肯定是不夠的,就必須使用多個字節(jié)表達(dá)一個符號。比如,簡體中文常見的編碼方式是GB2312,使用兩個字節(jié)表示一個漢字,所以理論上最多可以表示256x256=65536個符號。

    中文編碼的問題需要專文討論,這篇筆記不涉及。這里只指出,雖然都是用多個字節(jié)表示一個符號,但是GB類的漢字編碼與后文的Unicode和UTF-8是毫無關(guān)系的。

    3.Unicode

    正如上一節(jié)所說,世界上存在著多種編碼方式,同一個二進(jìn)制數(shù)字可以被解釋成不同的符號。因此,要想打開一個文本文件,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現(xiàn)亂碼。為什么電子郵件常常出現(xiàn)亂碼?就是因?yàn)榘l(fā)信人和收信人使用的編碼方式不一樣。

    可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨(dú)一無二的編碼,那么亂碼問題就會消失。這就是Unicode,就像它的名字都表示的,這是一種所有符號的編碼。

    Unicode當(dāng)然是一個很大的集合,現(xiàn)在的規(guī)??梢匀菁{100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字“嚴(yán)”。具體的符號對應(yīng)表,可以查詢unicode.org,或者專門的漢字對應(yīng)表。

    4. Unicode的問題

    需要注意的是,Unicode只是一個符號集,它只規(guī)定了符號的二進(jìn)制代碼,卻沒有規(guī)定這個二進(jìn)制代碼應(yīng)該如何存儲。

    比如,漢字“嚴(yán)”的unicode是十六進(jìn)制數(shù)4E25,轉(zhuǎn)換成二進(jìn)制數(shù)足足有15位(100111000100101),也就是說這個符號的表示至少需要2個字節(jié)。表示其他更大的符號,可能需要3個字節(jié)或者4個字節(jié),甚至更多。

    這里就有兩個嚴(yán)重的問題,第一個問題是,如何才能區(qū)別unicode和ascii?計(jì)算機(jī)怎么知道三個字節(jié)表示一個符號,而不是分別表示三個符號呢?第二個問題是,我們已經(jīng)知道,英文字母只用一個字節(jié)表示就夠了,如果unicode統(tǒng)一規(guī)定,每個符號用三個或四個字節(jié)表示,那么每個英文字母前都必然有二到三個字節(jié)是0,這對于存儲來說是極大的浪費(fèi),文本文件的大小會因此大出二三倍,這是無法接受的。

    它們造成的結(jié)果是:1)出現(xiàn)了unicode的多種存儲方式,也就是說有許多種不同的二進(jìn)制格式,可以用來表示unicode。2)unicode在很長一段時間內(nèi)無法推廣,直到互聯(lián)網(wǎng)的出現(xiàn)。

    5.UTF-8

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

    UTF-8最大的一個特點(diǎn),就是它是一種變長的編碼方式。它可以使用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。剩下的沒有提及的二進(jìn)制位,全部為這個符號的unicode碼。

    下表總結(jié)了編碼規(guī)則,字母x表示可用編碼的位。

    Unicode符號范圍 | UTF-8編碼方式
    (十六進(jìn)制) | (二進(jìn)制)
    --------------------+---------------------------------------------
    0000 0000-0000 007F | 0xxxxxxx
    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    下面,還是以漢字“嚴(yán)”為例,演示如何實(shí)現(xiàn)UTF-8編碼。

    已知“嚴(yán)”的unicode是4E25(100111000100101),根據(jù)上表,可以發(fā)現(xiàn)4E25處在第三行的范圍內(nèi)(0000 0800-0000 FFFF),因此“嚴(yán)”的UTF-8編碼需要三個字節(jié),即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,從“嚴(yán)”的最后一個二進(jìn)制位開始,依次從后向前填入格式中的x,多出的位補(bǔ)0。這樣就得到了,“嚴(yán)”的UTF-8編碼是“11100100 10111000 10100101”,轉(zhuǎn)換成十六進(jìn)制就是E4B8A5。

    6. Unicode與UTF-8之間的轉(zhuǎn)換

    通過上一節(jié)的例子,可以看到“嚴(yán)”的Unicode碼是4E25,UTF-8編碼是E4B8A5,兩者是不一樣的。它們之間的轉(zhuǎn)換可以通過程序?qū)崿F(xiàn)。

    在Windows平臺下,有一個最簡單的轉(zhuǎn)化方法,就是使用內(nèi)置的記事本小程序Notepad.exe。打開文件后,點(diǎn)擊“文件”菜單中的“另存為”命令,會跳出一個對話框,在最底部有一個“編碼”的下拉條。

    里面有四個選項(xiàng):ANSI,Unicode,Unicode big endian 和 UTF-8。

    1)ANSI是默認(rèn)的編碼方式。對于英文文件是ASCII編碼,對于簡體中文文件是GB2312編碼(只針對Windows簡體中文版,如果是繁體中文版會采用Big5碼)。

    2)Unicode編碼指的是UCS-2編碼方式,即直接用兩個字節(jié)存入字符的Unicode碼。這個選項(xiàng)用的little endian格式。

    3)Unicode big endian編碼與上一個選項(xiàng)相對應(yīng)。我在下一節(jié)會解釋little endian和big endian的涵義。

    4)UTF-8編碼,也就是上一節(jié)談到的編碼方法。

    選擇完”編碼方式“后,點(diǎn)擊”保存“按鈕,文件的編碼方式就立刻轉(zhuǎn)換好了。

    7. Little endian和Big endian

    上一節(jié)已經(jīng)提到,Unicode碼可以采用UCS-2格式直接存儲。以漢字”嚴(yán)“為例,Unicode碼是4E25,需要用兩個字節(jié)存儲,一個字節(jié)是4E,另一個字節(jié)是25。存儲的時候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。

    這兩個古怪的名稱來自英國作家斯威夫特的《格列佛游記》。在該書中,小人國里爆發(fā)了內(nèi)戰(zhàn),戰(zhàn)爭起因是人們爭論,吃雞蛋時究竟是從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開。為了這件事情,前后爆發(fā)了六次戰(zhàn)爭,一個皇帝送了命,另一個皇帝丟了王位。

    因此,第一個字節(jié)在前,就是”大頭方式“(Big endian),第二個字節(jié)在前就是”小頭方式“(Little endian)。

    那么很自然的,就會出現(xiàn)一個問題:計(jì)算機(jī)怎么知道某一個文件到底采用哪一種方式編碼?

    Unicode規(guī)范中定義,每一個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫做”零寬度非換行空格“(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。這正好是兩個字節(jié),而且FF比FE大1。

    如果一個文本文件的頭兩個字節(jié)是FE FF,就表示該文件采用大頭方式;如果頭兩個字節(jié)是FF FE,就表示該文件采用小頭方式。

    8. 實(shí)例

    下面,舉一個實(shí)例。

    打開”記事本“程序Notepad.exe,新建一個文本文件,內(nèi)容就是一個”嚴(yán)“字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8編碼方式保存。

    然后,用文本編輯軟件UltraEdit中的”十六進(jìn)制功能“,觀察該文件的內(nèi)部編碼方式。

    1)ANSI:文件的編碼就是兩個字節(jié)“D1 CF”,這正是“嚴(yán)”的GB2312編碼,這也暗示GB2312是采用大頭方式存儲的。

    2)Unicode:編碼是四個字節(jié)“FF FE 25 4E”,其中“FF FE”表明是小頭方式存儲,真正的編碼是4E25。

    3)Unicode big endian:編碼是四個字節(jié)“FE FF 4E 25”,其中“FE FF”表明是大頭方式存儲。

    4)UTF-8:編碼是六個字節(jié)“EF BB BF E4 B8 A5”,前三個字節(jié)“EF BB BF”表示這是UTF-8編碼,后三個“E4B8A5”就是“嚴(yán)”的具體編碼,它的存儲順序與編碼順序是一致的。

    9. 延伸閱讀

    * The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets(關(guān)于字符集的最基本知識)

    * 談?wù)刄nicode編碼

    * RFC3629:UTF-8, a transformation format of ISO 10646(如果實(shí)現(xiàn)UTF-8的規(guī)定)

  • posted on 2008-01-24 09:36 浪跡天涯 閱讀(13843) 評論(4)  編輯 收藏 引用 所屬分類: Other

    評論

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2008-01-24 10:07 浪跡天涯

    那么既然統(tǒng)一了編碼,如何兼容原先各國的文字編碼呢?


      這個時候就需要codepage了。


      什么是codepage?codepage就是各國的文字編碼和Unicode之間的映射表。


      比如簡體中文和Unicode的映射表就是CP936,點(diǎn)這里查看官方的映射表。


      以下是幾個常用的codepage,相應(yīng)的修改上面的地址的數(shù)字即可。


      codepage=936 簡體中文GBK


      codepage=950 繁體中文BIG5


      codepage=437 美國/加拿大英語


      codepage=932 日文


      codepage=949 韓文


      codepage=866 俄文


      codepage=65001 Unicode UFT-8


      最后一個65001,據(jù)個人理解,應(yīng)該只是一個虛擬的映射表,實(shí)際只是一個算法而已。


      從936中隨意取一行,例如:


      0x9993 0x6ABD #CJK UNIFIED IDEOGRAPH


      前面的編碼是GBK的編碼,后面的是Unicode。
      回復(fù)  更多評論   

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2010-07-09 17:06 TerryEVANS

    I strictly recommend not to wait until you earn enough amount of cash to order goods! You can take the <a href="http://bestfinance-blog.com">loan</a> or just short term loan and feel comfortable   回復(fù)  更多評論   

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2010-07-18 13:38 custom term papers

    I state that college students must look through the character essays they purchase from buy research paper service to make better their writing skills.   回復(fù)  更多評論   

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2010-07-24 08:28 buy essay papers

    Dream about well written academic papers? That's not hard! You just have to buy online essays at the experienced custom papers completing corporations for good prices.   回復(fù)  更多評論   

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2010-10-07 14:02 essay writers

    If settle to compose the non-plagiarized essay, you should get know that that demands a long period of time! Some students fail their custom term paper, just because they are not experienced enough! It is tragic, but the essay writing services will support such people any time they need.   回復(fù)  更多評論   

    # re: gbk, gb2312,big5,unicode,utf-8,utf-16之間的關(guān)系 2013-06-21 01:27 City of Doral

    City of Doral offers numerous quality services.   回復(fù)  更多評論   

    <2008年1月>
    303112345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(22)

    隨筆分類(30)

    隨筆檔案(29)

    文章分類

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品一区二区a| 亚洲人体一区| 亚洲黄网站黄| 久久久久久夜| 欧美影院视频| 久久精品国产999大香线蕉| 一区二区动漫| 亚洲图片欧美一区| 一区二区国产精品| 亚洲一区国产精品| 久久久久久久久久久久久久一区| 中文在线资源观看网站视频免费不卡 | 亚洲毛片av| 极品少妇一区二区三区精品视频| 国产一区视频在线观看免费| 国产一区二区中文| 亚洲国产精品999| 一区二区高清在线观看| 亚洲男女毛片无遮挡| 欧美国内亚洲| 欧美激情第3页| 99热免费精品在线观看| 欧美11—12娇小xxxx| 久久夜色精品国产| 亚洲精品系列| 韩国成人精品a∨在线观看| 欧美高清你懂得| 一区二区三区黄色| 免费成人美女女| 一区二区三区国产在线观看| 国产欧美91| 欧美精品97| 91久久国产自产拍夜夜嗨| 亚洲一区二区综合| 狂野欧美激情性xxxx| 欧美暴力喷水在线| 在线观看91精品国产麻豆| 夜夜爽夜夜爽精品视频| 久久av红桃一区二区小说| 日韩视频精品在线| 久久综合狠狠| 久久九九全国免费精品观看| 国产精品久久久久久五月尺| 亚洲人成在线观看一区二区| 久久久精品免费视频| 亚洲人成7777| 母乳一区在线观看| 中日韩高清电影网| 亚洲片在线观看| 免费观看在线综合| 在线日韩视频| 久久综合99re88久久爱| 先锋影音久久久| 美国十次成人| 一个色综合导航| 亚洲视屏一区| 国产精品美女主播在线观看纯欲| 91久久久久久久久久久久久| 美女精品自拍一二三四| 欧美电影免费观看高清| 一区二区三区色| 欧美激情成人在线| 欧美激情亚洲另类| 激情综合视频| 久久亚裔精品欧美| 久久久久在线| 亚洲国产99精品国自产| 最近中文字幕mv在线一区二区三区四区 | 欧美一区二区三区四区夜夜大片 | 一本色道久久| 欧美激情在线| 欧美xxxx在线观看| 快射av在线播放一区| 久久av红桃一区二区小说| 午夜精品理论片| 亚洲私人影院| 亚洲激情午夜| 在线免费观看一区二区三区| 久久亚洲精品视频| 欧美视频免费| 欧美本精品男人aⅴ天堂| 国产精品video| 欧美激情精品久久久久久变态| 久久综合九色99| 欧美一区成人| 噜噜噜躁狠狠躁狠狠精品视频| 一区二区激情小说| 久久精品女人天堂| 性高湖久久久久久久久| 欧美电影免费观看网站 | 久久亚洲风情| 欧美大胆人体视频| 亚洲淫片在线视频| 一区二区激情视频| 欧美日韩免费一区二区三区视频 | 亚洲免费在线| 麻豆精品传媒视频| 久久综合色天天久久综合图片| 在线免费观看视频一区| 日韩网站在线观看| 欧美在线一级视频| 欧美日韩国产黄| 老鸭窝91久久精品色噜噜导演| 欧美三级在线播放| 亚洲自拍三区| 亚洲免费观看高清完整版在线观看| 亚洲激情影视| 欧美在线视频一区二区三区| 亚洲电影第三页| 一本色道久久综合| 欧美一二三区精品| 欧美电影免费观看大全| 国产精品久久久久91| 国语自产精品视频在线看一大j8| 亚洲精品乱码久久久久久按摩观| 宅男精品导航| 巨胸喷奶水www久久久免费动漫| 亚洲精品在线观| 亚洲福利视频网| 一本一本久久| 玖玖综合伊人| 国产精品综合| 亚洲精品无人区| 久久久精品免费视频| 亚洲毛片一区二区| 久久成人一区二区| 欧美三区美女| 最新中文字幕亚洲| 久久精品一区二区三区中文字幕| 欧美一区二区女人| 91久久精品国产91久久性色| 久久国产精品久久久| 日韩视频免费看| 国产日韩成人精品| 欧美日韩精品一区二区天天拍小说 | 亚洲精品影视| 国产精品私拍pans大尺度在线| 久久久久久久一区二区| 亚洲美女视频| 最近看过的日韩成人| 久久网站热最新地址| 午夜精品福利在线观看| 99视频一区二区| 欧美在线观看视频在线| 久久精品一区二区三区不卡牛牛| 亚洲精品看片| 欧美激情一二区| 欧美激情二区三区| 欧美激情a∨在线视频播放| 久久精品亚洲| 老色批av在线精品| 久久精品主播| 亚洲国产精品日韩| 91久久一区二区| 一本大道久久a久久综合婷婷| 欧美一区二区三区视频在线观看 | 亚洲欧美第一页| 欧美风情在线观看| 午夜日韩在线| 国产伦精品一区二区三区免费迷| 免费成人美女女| 亚洲欧美日韩国产综合| 亚洲欧美怡红院| 久久激情综合网| 久久综合999| aa亚洲婷婷| 欧美在线亚洲综合一区| 美女免费视频一区| 久久成人免费网| 亚洲第一黄网| 亚洲精品女人| 一区二区三区欧美日韩| 欧美日韩人人澡狠狠躁视频| 一区二区三区你懂的| 日韩一级在线观看| 国产精品久久久久免费a∨大胸| 一区二区免费在线观看| 亚洲精品一二三区| 国产精品yjizz| 欧美在线日韩在线| 久久久噜久噜久久综合| 亚洲国产精品一区在线观看不卡| 欧美激情一区二区三区| 欧美激情小视频| 亚洲免费视频一区二区| 欧美亚洲综合网| 亚洲高清123| 日韩亚洲欧美一区| 国产精品网站在线播放| 欧美一区三区二区在线观看| 欧美激情久久久久久| 亚洲第一在线视频| 久久久久久久久久久久久女国产乱 | 欧美 日韩 国产 一区| 日韩亚洲精品电影| 久久久久这里只有精品| 激情成人亚洲| 久久中文字幕一区二区三区| 99在线热播精品免费| 欧美成人69av|