編碼的引入
ASCII
有人用 0x41 代表a,有人用 0x81 表示。語言不通,不同的計(jì)算機(jī)無法交流。美國人很早發(fā)現(xiàn)了這種問題,為便于交流指定了編碼標(biāo)準(zhǔn),于是有了:
ASCII(American Standard Code for Information)
ASCII碼是7位編碼,但由于計(jì)算機(jī)基本處理單位為字節(jié)(1byte = 8bit),所以一般仍以一個(gè)字節(jié)來存放一個(gè)ASCII字符。每一個(gè)字節(jié)中多余出來的一位(最高位)在計(jì)算機(jī)內(nèi)部通常保持為0。
ASCII被定為國際標(biāo)準(zhǔn)之后的代號(hào)為ISO-646
ASCII 解決了美國人的問題,但很快,其他國家發(fā)現(xiàn)了這個(gè)編碼不能滿足自己國家的需要。法國、德國等國家暫且不說,英國都發(fā)現(xiàn)ASCII有問題:英鎊符號(hào)“£”去哪兒了?現(xiàn)在好了,既想與ASCII兼容,有要添加ASCII沒有的文字符號(hào),怎么辦?擴(kuò)展一下吧!
由于ASCII碼只使用了7個(gè)二進(jìn)制位,也就是說一個(gè)字節(jié)可以表示的256個(gè)數(shù)字中,它僅使用了0~127這128個(gè)碼位,剩下的128個(gè)碼位便可以用來做擴(kuò)展,用來表示一些特定語言所獨(dú)有的字符
因此對這多余的128個(gè)碼位的不同擴(kuò)展,就形成了一系列ISO-8859-*的標(biāo)準(zhǔn)。例如為英語作了專門擴(kuò)展的字符集編碼標(biāo)準(zhǔn)編號(hào)為ISO-8859-1,也叫做Latin-1。
ISO-8859-*(*代表1~11,13~16)共15個(gè)編碼方案,解決了拉丁字母的語言(主要是歐洲國家的語言),使用西里爾字母的東歐語言、希臘語、泰語、現(xiàn)代阿拉伯語、希伯來語等。
*這些編碼方案在當(dāng)時(shí)解決了這些國家的問題,但不同的編碼如同軍閥割據(jù),同一勢力范圍內(nèi)交流沒問題,但不能普遍通用。比如 \xA3 在使用 Latin-1 的國家看來,是英鎊符號(hào)“£”,而在使用 Latin-2的國家看來,卻是另一個(gè)符號(hào) “?”。而且無法在一個(gè)文件內(nèi)同時(shí)出現(xiàn)這兩個(gè)符號(hào)。這個(gè)問題的解決,需要unicode。
ISO-2022 與 EUC
ISO-8859-*解決了多數(shù)語言的編碼問題,可是,漢語、日語及韓語字?jǐn)?shù)眾多,無法用單一個(gè)8位字符來表達(dá),也就是無法通過類似 ISO-8859-*的方式解決。于是有了 ISO-2022。
ISO-2022提供了這樣一種技術(shù),它能在一種字符編碼中支持多種字符集,可以用8位或16位來表示一個(gè)文字(字符),是一種變長的編碼,這樣,就能表示中日韓的字符了。該編碼還有個(gè)顯著的特點(diǎn),就是所有的字節(jié)都是以0開始的。
ISO-2022在日本用的比較普遍,在中國反倒是很少使用。盡管如此,還是用中文的ISO-2022-CN 簡單說一下:
在繼續(xù)之前,我們先提下GB2312:GB2312 中規(guī)定了漢字的區(qū)位碼(對應(yīng)的二進(jìn)制表,可以看做后面說的編碼方案)。那么,如果指定 ISO-2022 (等同GB 2311) 作為為其包裝方式(用來避免和ASCII的沖突)。
這里不得不介紹下ASCII控制字符了,既ASCII的0-31位表示其實(shí)都不是字符的編碼而是用作它途
附上一張表:
0 0x00 NUL空
|
11 0x0b VT垂直制表
|
22 0x16 SYN空轉(zhuǎn)同步
|
1 0x01 SOH標(biāo)題開始
|
12 0x0c FF走紙控制
|
23 0x17 ETB信息組傳送結(jié)束
|
2 0x02 STX正文開始
|
13 0x0d CR回車
|
24 0x18 CAN作廢
|
3 0x03 ETX正文結(jié)束
|
14 0x0e SO移位輸出
|
25 0x19 EM紙盡
|
4 0x04 EOY傳輸結(jié)束
|
15 0x0f SI移位輸入
|
26 0x1a SUB換置
|
5 0x05 ENQ詢問字符
|
16 0x10 DLE空格
|
27 0x1b ESC換碼
|
6 0x06 ACK承認(rèn)
|
17 0x11 DC1設(shè)備控制1
|
28 0x1c FS文字分隔符
|
7 0x07 BEL報(bào)警
|
18 0x12 DC2設(shè)備控制2
|
29 0x1d GS組分隔符
|
8 0x08 BS退一格
|
19 0x13 DC3設(shè)備控制3
|
30 0x1e RS記錄分隔符
|
9 0x09 HT橫向列表
|
20 0x14 DC4設(shè)備控制4
|
31 0x1f US單元分隔符
|
10 0x0a LF換行
|
21 0x15 NAK否定
|
127 0xff DEL刪除
|
漢字“文”字在46區(qū)36位,然后用 ISO 2022 包裝時(shí),字節(jié)序列是:
<ESC>$ ) A <SO> <0x4E> <0x44> <SI>
ISO2022使用“逃逸字串”(Escape sequence)。逃逸字串由1個(gè)“ESC”字符(0x1B),再由兩至三個(gè)字串組成。此標(biāo)記代表它后面的字符,屬于下表字符集的文字。
<ESC> 是字節(jié) 0x1b,表示換碼
然后ESC $ ) A 轉(zhuǎn)為GB2312-1980 (2 bytes per character)
<SO> 是字節(jié) 0x0e,表示脫離普通 ASCII 編碼模式,進(jìn)入特殊編碼模式(這兒進(jìn)入的是 GB 2312-1980 編碼方式)
<SI> 是字節(jié) 0x0f,表示返回普通 ASCII 編碼模式
第一字節(jié) 0x4E 是在區(qū)號(hào) 46 的基礎(chǔ)上加上32,以避開 ASCII 的控制符區(qū)(<32)
第二字節(jié) 0x44 是在位號(hào) 36 的基礎(chǔ)上加上32,以避開 ASCII 的控制符區(qū)(<32)
ISO/IEC2022 - Wikipedia, the free encyclopedia
前面說了,ISO-2022-CN 在國內(nèi)很少使用,那么國內(nèi)用的什么編碼方案呢?
那就是 EUC-CN:
EUC(Extended Unix Code),是一個(gè)主要用于日文、韓文、簡體中文的多字節(jié)編碼系統(tǒng),它基于ISO-2020標(biāo)準(zhǔn)。
它使用了一些兼容于ISO-2022區(qū)位碼的94x94編碼表,把每個(gè)區(qū)位加上0xA0來表示,以便兼容于ASCII。
今天通常說的 GB2312 編碼都是指 EUC(ISO-2020) 包裝的GB2312 編碼。
Extended Unix Code - Wikipedia, thefree encyclopedia
EUC-GB2312 與區(qū)位碼的關(guān)系:
第1字節(jié) = 區(qū)碼 + 32 + 0x80
第2字節(jié) = 位碼 + 32 + 0x80
所以,“文”字的 EUC-GB2312 編碼是 0xCE 0xC4,用記事本保存一個(gè)“文”,然后用FlexHex查看
當(dāng)然,大端小端問題和BOM一起說。
Unicode
Unicode是由于傳統(tǒng)的字符編碼方式的局限性而產(chǎn)生的,例如:
ISO8859所定義的字符雖然在不同的國家中廣泛地使用,可是在不同國家間卻經(jīng)常出現(xiàn)不相容的情況。
很多傳統(tǒng)的編碼方式都具有一個(gè)共通的問題,即其容許電腦進(jìn)行雙語環(huán)境式的處理(通常是ASCII以及其本地語言),但卻無法同時(shí)支援多語言環(huán)境式的處理(比如同是處理中文和日文)。
于是一個(gè)將所有國家所有語種的所有文字進(jìn)行統(tǒng)一編碼的方案開始了...
Unicode與UCS
1980年代,有兩個(gè)組織分別開始開發(fā)適用于各國語言的通用碼,但不久他們便發(fā)現(xiàn)了對方的存在。
Unicode組織,由多家計(jì)算機(jī)軟件公司,還包括一些出版行業(yè)的公司共同發(fā)起的。采用16位編碼空間。
ISO-10646項(xiàng)目組,UniversalCharacter Set(UCS),采用31位編碼空間。
ISO與Unicode是兩個(gè)不同的組織,因此最初制定了不同的標(biāo)準(zhǔn);但自從unicode2.0開始,unicode采用了與ISO 10646-1相同的字庫和字碼,ISO也承諾ISO10646將不會(huì)給超出0×10FFFF的UCS-4編碼賦值,使得兩者保持一致。
最終,兩者統(tǒng)一了抽象字符集(即任何一個(gè)在Unicode中存在的字符,在UCS中也存在),且最靠前的65535個(gè)字符也統(tǒng)一了字符的編碼。
現(xiàn)在可以認(rèn)為UCS和UNICODE是一個(gè)概念。
字符編碼方案
在傳統(tǒng)意義上,沒有字符集和編碼的區(qū)分,比如GB2312、Latin1等都是既指代字符集又指代編碼方案。
編碼字符集 CodedCharacter Set
字符編碼 CharacterEncoding
按照慣例,人們認(rèn)為字符集和字符編碼是同義詞,但現(xiàn)代的編碼方案 Unicode,沒有遵循這種慣例。
Unicode 是一個(gè)字符集合,它給集合中的每個(gè)字符都指定一了個(gè)代號(hào)code point。
字符到代號(hào)的過程。更簡單的說就是指Unicode字符平面映射.(U+0000~ U+FFFF 這個(gè)序列中,每一個(gè)代號(hào)對應(yīng)一個(gè)字符,不同的字符在字符平面上都有其對應(yīng)的代號(hào))
當(dāng)我們要把這個(gè)代號(hào)存到計(jì)算機(jī)中時(shí),需要把它變成一個(gè)字節(jié)的序列。
代號(hào)如果轉(zhuǎn)換成到機(jī)器序列(機(jī)器編碼)呢?這個(gè)過程有些可能為了節(jié)省空間而修改一些內(nèi)容(utf8,utf16)...
于是不同的變換方式引入了:
小結(jié)一下:
Unicode是規(guī)范,是編碼字符集,規(guī)定了字符到字符平面代號(hào)的映射關(guān)系,其有UCS2和UCS4兩種格式。UCS2和UCS4都是定長的,而不是字符編碼方案。
UTF是Unicode Transformation Format,是Unicode的實(shí)現(xiàn),是字符編碼方案,規(guī)定了字符平面代號(hào)到機(jī)器編碼(保存?zhèn)鬏敚┑年P(guān)系。
它分為utf-8,utf-16,utf-32幾種形式,其中utf-8和utf-16都是變長的,而utf-32是定長編碼。(其實(shí)還有utf-7等其它編碼存在)
基本上可以理解為UTF-32就是UCS4,而UTF-16和UCS2兼容,只是UTF-16擴(kuò)展了一些。
UTF
UTF-8,8bit編碼, ASCII不作變換, 其他字符做變長編碼, 每個(gè)字符1-6 byte. 通常作為外碼.
有以下優(yōu)點(diǎn):
1.與CPU字節(jié)順序無關(guān), 可以在不同平臺(tái)之間交流
2.容錯(cuò)能力高, 任何一個(gè)字節(jié)損壞后, 最多只會(huì)導(dǎo)致一個(gè)編碼碼位損失, 不會(huì)鏈鎖錯(cuò)誤(如GB碼錯(cuò)一個(gè)字節(jié)就會(huì)整行亂碼)
UTF-8用一個(gè)字節(jié)表示ASCI字符,用兩個(gè)字節(jié)表示西歐字符,用三個(gè)字符表示亞洲的大部分字符。
UTF-16,16bit編碼, 是變長碼, UTF-16則是unicode的preferred encoding。
UCS-2與UTF-16在對前65536個(gè)字符的處理上完全相同,唯一的區(qū)別只在于 UCS-2 不支持surrogate pair機(jī)制,即是說,UCS-2只能對前65536個(gè)字符編碼,對其后的字符毫無辦法。
UTF-16是windows平臺(tái)上主要使用的編碼方案,一般windows上所說的UNICODE就是指它了.
UTF-32,僅使用了unicode范圍(0到0x10FFFF)的32位編碼, 相當(dāng)于UCS-4的子集.
BOM
UTF還涉及到字節(jié)序的問題。字節(jié)順序標(biāo)記(Byte Order Mark, 簡稱BOM)出現(xiàn)在Unicode流開端,說明編碼類型。BOM是一個(gè)有點(diǎn)小聰明的想法。
關(guān)于字節(jié)序問題。例如“奎”的Unicode編碼是U+594E,“乙”的Unicode編碼是U+4E59。如果我們收到UTF-16字節(jié)流“594E”,那么這是“奎”還是“乙”?
Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM。BOM不是“Bill OfMaterial”的BOM表,而是Byte OrderMark。BOM是一個(gè)有點(diǎn)小聰明的想法:
在UCS編碼中有一個(gè)叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是0xFEFF。(標(biāo)準(zhǔn)其實(shí)算是Big Endian的)
Zero-widthnon-breaking space (ZWNBSP) is a deprecated use of the Unicode character atcode point U+FEFF. Character U+FEFF is intended for use as a Byte Order Markat the start of a file. However, if encounteredelsewhere it
should, according to Unicode, be treated as a "zero-widthnon-breaking space". The deliberate use of U+FEFF for this purpose is nowdeprecated, with U+2060 word joiner (HTML: ⁠) strongly preferred.
而不同的編碼方案解析這個(gè)"ZERO WIDTH NO-BREAKSPACE"字符 時(shí)就會(huì)產(chǎn)生不同的結(jié)果:
編碼方式
|
big endian
|
little endian
|
UTF-16 big endian
|
FE FF
|
FF FE(Windows)
|
UTF-32 bign endian
|
00 00 FE FF
|
FF FE 00 00
|
UTF-8 little endian (gcc)
|
EF BB BF
|
EF BB BF
|
由于utf-8的big endian和littleendian結(jié)果都是一樣的,linux下就默認(rèn)不需要BOM,而Windows下默認(rèn)沒有BOM的文本是DBCS編碼(GBK),所以Windows下如果要使用utf-8的話就需要帶上BOM了,這是一個(gè)不兼容的地方,linux下如果帶上utf-8的BOM就會(huì)報(bào)錯(cuò)。
注意:在UCS中是不存在的"U+FFFE" code point的,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中。UCS規(guī)范建議我們在傳輸字節(jié)流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。
這樣傳輸U(kuò)nicode字符時(shí),如果接收者收到FEFF,就表明他是utf-16,并且它的字節(jié)序是Big-Endian的;如果是FFFE,就表明字節(jié)序是Little-Endian的。
因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。我們可以在保存和讀取文本文件時(shí)用到它。
GB18030
GB18030: Unicode 的GBK擴(kuò)展版本, 覆蓋了所有unicode編碼, 地位等同于UTF-8, UTF-16, 是一種unicode編碼形式. 變長編碼, 用單字節(jié)/雙字節(jié)/4字節(jié)對字符編碼
GB18030向下兼容GB2312/GBK.
GB18030 是中國所有非手持/嵌入式計(jì)算機(jī)系統(tǒng)的強(qiáng)制實(shí)施標(biāo)準(zhǔn).
base64
Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一
Base64要求把每三個(gè)8Bit的字節(jié)轉(zhuǎn)換為四個(gè)6Bit的字節(jié)(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個(gè)8Bit的字節(jié),也就是說,可以估算編碼后數(shù)據(jù)長度大約為原長的135.1%。
ASCII中有很多字符是不可打印的,26個(gè)英文字母大小寫加上0~9已經(jīng)有62個(gè)字符了,再加上"+"和"/"正好湊了64和字符
base64可以用來將二進(jìn)制的字節(jié)序列數(shù)據(jù)編碼成ASCII字符序列構(gòu)成的文本,也就是說圖片之類的也可以用base64直接編碼.
HZ
將 EUC-GB2312 的各字節(jié)最高位去掉,再在前后分別加上轉(zhuǎn)義字符,
例如“文”:
~{<0x4E> <0x44> ~}
源文件內(nèi)的編碼與執(zhí)行時(shí)字符編碼
我們先列個(gè)表,看看兩種亂碼分別在那種情況下出現(xiàn):
我們只列舉大家最常用的3個(gè)編譯器(微軟VS的中的cl,Mingw中的g++,Linux下的g++),源代碼分別采用 GBK 和 不帶BOM的UTF-8 以及 帶BOM的UTF-8 這3中編碼進(jìn)行保存。
源代碼的編碼
|
編譯器
|
結(jié)果
|
GBK
|
cl
|
1
|
*
|
mingw-g++
|
1
|
*
|
g++
|
1
|
UTF-8(不帶BOM)
|
cl
|
2
|
mingw-g++
|
2
|
g++
|
2
|
*
|
UTF-8(帶BOM)
|
cl
|
1
|
mingw-g++
|
2
|
g++
|
編譯失敗
|
采用3種不同編碼保存的源代碼文件,分別用3種不同的編譯器編譯,形成9種組合,除掉一種不能工作的情況,兩種亂碼出現(xiàn)的情況各占一半。
從中我們也可以看出,亂碼和操作系統(tǒng)原本是沒有關(guān)系的。
但我們在 Windows 一般用的GBK,linux一般用的是不帶BOM的UTF-8。
如果我們只考慮帶*的情況,也可以說兩種亂碼和系統(tǒng)有關(guān)。
默認(rèn)情況下
源文件編碼
|
編譯器
|
"我是中文" 內(nèi)存中編碼
|
GBK
|
cl
|
成功轉(zhuǎn)成Unicode
|
gcc
|
失敗,編譯不過
|
UTF8(帶BOM)
|
cl
|
成功
|
gcc
|
成功
|
UTF8(不帶BOM)
|
cl
|
失敗,輸出亂碼
|
gcc
|
成功
|
對 cl
只要源代碼帶BOM,如果源代碼有BOM,對于不帶L的字符串,直接轉(zhuǎn)GBK。
猜想:對于帶L的字符串,直接轉(zhuǎn)ucs2?
如果不帶BOM,編譯器默認(rèn)源代碼文本是gbk編碼,再進(jìn)行相關(guān)的轉(zhuǎn)換。
于是,當(dāng)我們用不帶BOM的utf8格式時(shí),cl將其按照gbk解碼。
對 gcc
默認(rèn)將所有的字符串都按照utf8解碼。帶不帶utf8的BOM都不影響。
其實(shí)gcc是支持其他編碼的,只不過需要通過編譯選項(xiàng)來指定。比如對gbk:gcc main.c-finput-charset=gbk -o main
VS2010如果源碼文件不帶BOM的話,是不自動(dòng)轉(zhuǎn)換編碼的,直接使用源碼中的編碼。使用BOM則會(huì)自動(dòng)轉(zhuǎn)換成GBK編碼。
要禁止編碼自動(dòng)轉(zhuǎn)換成GBK,可以加一個(gè)指令,更改執(zhí)行字符集:
#pragmaexecution_character_set("UTF-8")
上面提到的是"文件保存時(shí)需要BOM",也就是它需要知道"源碼文件的編碼",才能知道如何轉(zhuǎn)換成"執(zhí)行時(shí)字符集"??梢韵氲?,一旦去掉BOM后,cl編譯器只能靠猜測,這是不可靠的。
// 下面的代碼在簡體中文Windows下的MVSC2010下,無法通過編譯
// 說明windows下源代碼保存需要BOM,不帶BOM直接當(dāng)做GBK
// utf8 encoded c++ source file without BOM
#include<iostream>
int main()
{
std::cout<<sizeof("不帶BOM是不給轉(zhuǎn)換編碼的,而使用了BOM后,會(huì)自動(dòng)將UTF-8編碼轉(zhuǎn)換成GBK。");
return0;
}
|
但是 目前GCC編譯器不接受帶有BOM的源代碼文件,而且Linux/UNIX 并沒有使用 BOM,因?yàn)樗鼤?huì)破壞現(xiàn)有的 ASCII 文件的語法約定,所以問題應(yīng)該還只是部分解決。
再來說一說CodePage
代碼頁 - 維基百科,自由的百科全書
在1980年前,仍然沒有任何國際標(biāo)準(zhǔn)如ISO-8859或Unicode來定義如何擴(kuò)展US-ASCII編碼以便非英語國家的用戶使用.于是很多IT 廠商發(fā)明了他們自己的編碼,并且使用了難以記憶的數(shù)目來標(biāo)識(shí): ISO-8859-*,ISO-2022 與 EUC,…
代碼頁是字符集編碼的別名,也稱"內(nèi)碼表",是特定語言的字符集的一張表。早期,代碼頁是IBM稱呼計(jì)算機(jī)的BIOS所支持的字符集編碼。當(dāng)時(shí)通用的操作系統(tǒng)都是命令行界面,這些操作系統(tǒng)直接使用BIOS提供的字符繪制功能來顯示字符。這些BIOS代碼頁也被稱為OEM代碼頁。圖形操作系統(tǒng)使用自己的字符呈現(xiàn)引擎(rendering engine),可以支持多個(gè)不同的字符集編碼,這類代碼頁被稱作ASCII代碼頁。
早期IBM和微軟內(nèi)部使用數(shù)字來標(biāo)記不同的編碼字符集,不同的廠商對同一個(gè)字符集編碼使用各自不同的名稱。例如,UTF-8在IBM稱作代碼頁1208, 在微軟稱作代碼頁65001, 在SAP稱作代碼頁4110.
1987年4月,IBM發(fā)布了PC-DOS 3.3,正式開始使用16比特的無符號(hào)整數(shù)標(biāo)識(shí)不同的代碼頁。這時(shí)的PC機(jī)使用CGA顯示系統(tǒng)的字符界面,繪制不同語言的字符依靠BIOS硬件廠商提供的功能。如果想更換所支持的字符集,就必須換上支持該字符集的ROM芯片。微軟作為DOS操作系統(tǒng)的軟件廠商,并不擁有繪制這些字符集的知識(shí)產(chǎn)權(quán)。所以這些字符集的繪制實(shí)現(xiàn),稱作OEM代碼頁。最常見、最具代表性的OEM代碼頁是"IBM PC或MS-DOS 代碼頁437"。
隨著圖形用戶界面操作系統(tǒng)的廣泛使用(最初被廣為接受的是Windows 3.1),操作系統(tǒng)具有了字符繪制的功能。微軟在Windows操作系統(tǒng)沒有轉(zhuǎn)向UTF-16作為內(nèi)碼實(shí)現(xiàn)之前(也就是在Windows 2000之前),針對不同的使用地區(qū)與國家,定義了一系列的支持不同語言字符集的代碼頁,被稱作"Windows (或ANSI) 代碼頁"。代表性的是實(shí)現(xiàn)了ISO-8859-1的代碼頁1252.
要使用CodePage的原因還有,很多符號(hào)形狀(字體)的映射都是基于本地方案,既不是unicode字體。(個(gè)人猜測)
字符內(nèi)碼(charcter code)指的是用來代表字符的內(nèi)碼.讀者在輸入和存儲(chǔ)文檔時(shí)都要使用內(nèi)碼,內(nèi)碼分為
單字節(jié)內(nèi)碼 -- Single-Byte character sets (SBCS),可以支持256個(gè)字符編碼.
雙字節(jié)內(nèi)碼 -- Double-Byte character sets)(DBCS),可以支持65000個(gè)字符編碼.主要用來對大字符集的東方文字進(jìn)行編碼.
codepage指的是一個(gè)經(jīng)過挑選的以特定順序排列的字符內(nèi)碼列表,對于早期的單字節(jié)內(nèi)碼的語種,codepage中的內(nèi)碼順序使得系統(tǒng)可以按照此列表來根據(jù)鍵盤的輸入值給出一個(gè)對應(yīng)的內(nèi)碼.對于雙字節(jié)內(nèi)碼,則給出的是MultiByte到Unicode的對應(yīng)表,這樣就可以把以Unicode形式存放的字符轉(zhuǎn)化為相應(yīng)的字符內(nèi)碼,或者反之,在Linux核心中對應(yīng)的函數(shù)就是utf8_mbtowc和utf8_wctomb.
現(xiàn)在來看這些Codpage 是不是很容易理解了?
同 Extended Unix Coding ( EUC )編碼大不一樣的是,下面所有的遠(yuǎn)東 codepage 都利用了C1控制碼{ 80.9F } 做為首字節(jié), 使用ASCII值 { =407E { 做為第二字節(jié),這樣才能包含多達(dá)數(shù)萬個(gè)雙字節(jié)字符,這表明在這種編碼之中小于3F的ASCII值不一定代表ASCII字符.
CP932
Shift-JIS包含日本語 charset JIS X 0201 (每個(gè)字符一個(gè)字節(jié)) 和 JIS X 0208 (每個(gè)字符兩個(gè)字節(jié)),所以 JIS X 0201平假名包含一個(gè)字節(jié)半寬的字符,其剩馀的60個(gè)字節(jié)被用做7076個(gè)漢字以及648個(gè)其他全寬字符的首字節(jié).同EUC-JP編碼區(qū)別的是,Shift-JIS沒有包含JIS X 202中定義的5802個(gè)漢字.
CP936
GBK擴(kuò)展了 EUC-CN 編碼( GB 2312-80編碼,包含 6763 個(gè)漢字)到Unicode (GB13000.1-93)中定義的20902個(gè)漢字,中國大陸使用的是簡體中文zh_CN.
CP949
UnifiedHangul(UHC) 是韓文 EUC-KR 編碼(KS C 5601-1992 編碼,包括2350 韓文音節(jié)和 4888 個(gè)漢字a)的超集,包含 8822個(gè)附加的韓文音節(jié)( 在C1中 )
CP950
是代替EUC-TW (CNS 11643-1992)的 Big5 編碼(13072 繁體 zh_TW 中文字)繁體中文,這些定義都在Ken Lunde的 CJK.INF中或者 Unicode 編碼表中找到.
特別的:和Unicode相關(guān)的CodePage
CP1200 — UCS-2LE Unicode 小端序
CP1201 — UCS-2BE Unicode 大端序
CP65000 — UTF-7 Unicode
CP65001 — UTF-8 Unicode
Linux下Codepage
在Linux下引入對Codepage的支持主要是為了訪問FAT/VFAT/FAT32/NTFS/NCPFS等文件系統(tǒng)下的多語種文件名的問題,目前在NTFS和FAT32/VFAT下的文件系統(tǒng)上都使用了Unicode,這就需要系統(tǒng)在讀取這些文件名時(shí)動(dòng)態(tài)將其轉(zhuǎn)換為相應(yīng)的語言編碼.因此引入了NLS支持.其相應(yīng)的程序文件在/usr/src/linux/fs/nls下:
Config.in,Makefile ,nls_base.c ,nls_cp437.c ,nls_cp737.c ,nls_cp775.c ,nls_cp850.c ,nls_cp852.c ,nls_cp855.c ,nls_cp857.c ,nls_cp860.c ,nls_cp861.c ,nls_cp862.c ,nls_cp863.c ,nls_cp864.c ,nls_cp865.c ,nls_cp866.c ,nls_cp869.c ,nls_cp874.c ,nls_cp936.c ,nls_cp950.c
,nls_iso8859-1.c ,nls_iso8859-15.c ,nls_iso8859-2.c ,ls_iso8859-3.c ,nls_iso8859-4.c ,nls_iso8859-5.c ,,nls_iso8859-6.c ,nls_iso8859-7.c ,nls_iso8859-8.c ,nls_iso8859-9.c ,nls_koi8-r.c
實(shí)現(xiàn)了下列函數(shù):
extern int utf8_mbtowc(__u16*,
const __u8*,
int);
extern int utf8_mbstowcs(__u16*,
const __u8*,
int);
extern int utf8_wctomb(__u8*, __u16,int);
extern int utf8_wcstombs(__u8*,
const __u16*,
int);
|
這樣在加載相應(yīng)的文件系統(tǒng)時(shí)就可以用下面的參數(shù)來設(shè)置Codepage:
對于Codepage 437 來說
mount-t vfat /dev/hda1 /mnt/1 -o codepage=437,iocharset=cp437
這樣在Linux下就可以正常訪問不同語種的長文件名了.
利用iconv函數(shù)族進(jìn)行編碼轉(zhuǎn)換
#include<iconv.h>
#pragma comment(lib,"iconv.lib")
int code_convert(char*from_charset,char*to_charset,constchar*inbuf,
size_t inlen,char*outbuf, size_t outlen)
{
iconv_t cd;
constchar**pin=&inbuf;
char**pout=&outbuf;
cd =iconv_open(to_charset,from_charset);
if (cd==0)
return-1;
memset(outbuf,0,outlen);
if (iconv(cd, pin,&inlen,pout,
&outlen)==-1)
return-1;
iconv_close(cd);
return0;
}
/* UTF-8 to GBK */
int u2g(constchar*inbuf,
size_t inlen, char*outbuf, size_t outlen)
{
return code_convert("UTF-8","GBK",inbuf,inlen,outbuf,outlen);
}
/* GBK to UTF-8 */
int g2u(constchar*inbuf,
size_t inlen, char*outbuf, size_t outlen)
{
return code_convert("GBK","UTF-8",
inbuf, inlen, outbuf, outlen);
}
|
用于char_set的參數(shù)列表
European languages
|
ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU,CP{1250,1251,1252,1253,1254,1257}, CP{850,866,1131}, Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, Mac{Cyrillic,Ukraine,Greek,Turkish},
Macintosh
|
Semitic languages
|
ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
|
Japanese
|
EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1
|
Chinese
|
EUC-CN, HZ, GBK,
CP936, GB18030, EUC-TW,BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, ISO-2022-CN-EXT
|
Korean
|
EUC?KR, CP949, ISO?2022?KR, JOHAB
|
Armenian
|
ARMSCII-8
|
Georgian
|
Georgian-Academy, Georgian-PS
|
Tajik
|
KOI8-T
|
Kazakh
|
PT154, RK1048
|
Thai
|
TIS-620, CP874, MacThai
|
Laotian
|
MuleLao-1, CP1133
|
Vietnamese
|
VISCII, TCVN, CP1258
|
Platform specifics
|
HP-ROMAN8, NEXTSTEP
|
Full Unicode
|
UTF-8,UCS-2, UCS-2BE,UCS-2LE,UCS-4, UCS-4BE, UCS-4LE,UTF-16, UTF-16BE, UTF-16LE,UTF-32, UTF-32BE,
UTF-32LE,UTF-7,C99,JAVA
|
Full Unicode, in terms of uint16_t or uint32_t
|
UCS-2-INTERNAL, UCS-4-INTERNAL
(with machine dependent endianness and alignment)
|
Locale dependent, in terms of char or wchar_t
|
char, wchar_t
(with machine dependent endianness and alignment, and with semantics depending on the OS and the current LC_CTYPE locale facet)
|
When configured with the option --enable-extra-encodings,
it also provides support for a few extra encodings:
|
European languages
|
CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125}
|
Semitic languages
|
CP864
|
Japanese
|
EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3
|
Chinese
|
BIG5-2003 (experimental)
|
Turkmen
|
TDS565
|
Platform specifics
|
ATARIST, RISCOS-LATIN1
|
The empty encoding name "" is equivalent to"char":
it denotes the locale dependent character encoding.
|
Windows下的編碼轉(zhuǎn)換
int ToUCS(unsignedchar*p,wchar_t*
pUCS,int codepage)
{
int len=0;
if(pUCS== NULL
|| p == NULL)
return-1;
len
=MultiByteToWideChar(codepage,0,p,-1,NULL,0);
MultiByteToWideChar(codepage,0,p,-1,pUCS,len);
return len;
}
int UCSTo(wchar_t* pUCS,char*p,int
codepage)
{
int len=0;
if(pUCS== NULL
|| pBIG5
== NULL)
return-1;
len
=WideCharToMultiByte(codepage,0,pUCS,-1,NULL,0,NULL,NULL);
WideCharToMultiByte(codepage,0,pUCS,-1,p,len,NULL,NULL);
len--;
return len;
}
|
WINBASEAPI int WINAPI
MultiByteToWideChar(
__in UINT CodePage,
__in DWORD dwFlags,
__in_bcount(cbMultiByte) LPCSTR lpMultiByteStr,
__in int cbMultiByte,
__out_ecount_opt(cchWideChar) __transfer(lpMultiByteStr) LPWSTR lpWideCharStr,
__in int cchWideChar);
WINBASEAPI int WINAPI
WideCharToMultiByte(
__in UINT CodePage,
__in DWORD dwFlags,
__in_ecount(cchWideChar) LPCWSTR lpWideCharStr,
__in int cchWideChar,
__out_bcount_opt(cbMultiByte) __transfer(lpWideCharStr) LPSTR lpMultiByteStr,
__in int cbMultiByte,
__in_opt LPCSTR lpDefaultChar,
__out_opt LPBOOL lpUsedDefaultChar);
|
codepage在MSDN定義如下
Bit
|
Code page
|
Description
|
ANSI
|
0
|
1252
|
Latin 1
|
1
|
1250
|
Latin 2: Eastern Europe
|
2
|
1251
|
Cyrillic
|
3
|
1253
|
Greek
|
4
|
1254
|
Turkish
|
5
|
1255
|
Hebrew
|
6
|
1256
|
Arabic
|
7
|
1257
|
Baltic
|
8
|
1258
|
VietNam
|
9 - 15
|
Reserved for ANSI
|
ANSI and OEM
|
16
|
874
|
Thai
|
17
|
932
|
Japanese, Shift-JIS
|
18
|
936
|
Chinese: Simplified chars—PRC and Singapore
ASCII、GB2312、GBK到GB18030 兼容
|
19
|
949
|
Korean Unified Hangeul Code (Hangeul TongHabHyung Code)
|
20
|
950
|
Chinese: Traditional chars—Hong Kong SAR, PRC and Taiwan
BIG5
|
21
|
1361
|
Korean (Johab)
|
22 - 29
|
Reserved for alternate ANSI and OEM
|
30 - 31
|
Reserved by system.
|
OEM
|
32 - 46
|
Reserved for OEM
|
47
|
1258
|
VietNam
|
48
|
869
|
IBM Greek
|
49
|
866
|
MS-DOS Russian
|
50
|
865
|
MS-DOS Nordic
|
51
|
864
|
Arabic
|
52
|
863
|
MS-DOS Canadian French
|
53
|
862
|
Hebrew
|
54
|
861
|
MS-DOS Icelandic
|
55
|
860
|
MS-DOS Portuguese
|
56
|
857
|
IBM Turkish
|
57
|
855
|
IBM Cyrillic; primarily Russian
|
58
|
852
|
Latin 2
|
59
|
775
|
Baltic
|
60
|
737
|
Greek; former 437 G
|
61
|
708
|
Arabic; ASMO 708
|
62
|
850
|
Western European/Latin 1
|
63
|
437
|
US
|
利用ICU進(jìn)行編碼轉(zhuǎn)換
IBM Globalization -ICU
#include<unicode/ucnv.h>
#ifdef _WIN32
#pragmacomment(lib,"icuuc.lib")
#endif
//返回0為成功,錯(cuò)誤代碼定義見后面
intconvert(constchar*
toConverterName,
constchar* fromConverterName,
char* target,
int32_t targetCapacity,
constchar* source,
int32_t sourceLength)
{
UErrorCode errorcode= U_ZERO_ERROR;
ucnv_convert(toConverterName,fromConverterName,target, targetCapacity, source, sourceLength,&errorcode
);
return errorcode;
}
int _tmain(int argc, _TCHAR*
argv[])
{
wchar_t aaa[]= L"中國人的系統(tǒng)上123323";
int alen= wcslen(aaa);
int blen=alen*2+sizeof(int);
char*abuff=newchar[blen];
int result= convert(
"gb2312",
"utf-16le", abuff, blen, (constchar*)aaa, alen);
cout<< abuff<< endl<<strlen(abuff)<<endl;
delete []abuff;
return0;
}
|
typedef enum UErrorCode{
/* The ordering of U_ERROR_INFO_START Vs U_USING_FALLBACK_WARNING looks weird
* and is that way because VC++ debugger displays first encountered constant,
* which is not the what the code is used for
*/
U_USING_FALLBACK_WARNING = -128, /**< A resource bundle lookup returned a fallback result (not an error) */
U_ERROR_WARNING_START = -128, /**< Start of information results (semantically successful) */
U_USING_DEFAULT_WARNING = -127, /**< A resource bundle lookup returned a result from the root locale (not an error) */
U_SAFECLONE_ALLOCATED_WARNING = -126, /**< A SafeClone operation required allocating memory (informational only) */
U_STATE_OLD_WARNING = -125, /**< ICU has to use compatibility layer to construct the service. Expect performance/memory usage degradation. Consider upgrading */
U_STRING_NOT_TERMINATED_WARNING = -124,/**< An output string could not be NUL-terminated because output length==destCapacity. */
U_SORT_KEY_TOO_SHORT_WARNING = -123, /**< Number of levels requested in getBound is higher than the number of levels in the sort key */
U_AMBIGUOUS_ALIAS_WARNING = -122, /**< This converter alias can go to different converter implementations */
U_DIFFERENT_UCA_VERSION = -121, /**< ucol_open encountered a mismatch between UCA version and collator image version, so the collator was constructed from rules. No impact to further function */
U_PLUGIN_CHANGED_LEVEL_WARNING = -120, /**< A plugin caused a level change. May not be an error, but later plugins may not load. */
U_ERROR_WARNING_LIMIT, /**< This must always be the last warning value to indicate the limit for UErrorCode warnings (last warning code +1) */
U_ZERO_ERROR = 0, /**< No error, no warning. */
U_ILLEGAL_ARGUMENT_ERROR = 1, /**< Start of codes indicating failure */
U_MISSING_RESOURCE_ERROR = 2, /**< The requested resource cannot be found */
U_INVALID_FORMAT_ERROR = 3, /**< Data format is not what is expected */
U_FILE_ACCESS_ERROR = 4, /**< The requested file cannot be found */
U_INTERNAL_PROGRAM_ERROR = 5, /**< Indicates a bug in the library code */
U_MESSAGE_PARSE_ERROR = 6, /**< Unable to parse a message (message format) */
U_MEMORY_ALLOCATION_ERROR = 7, /**< Memory allocation error */
U_INDEX_OUTOFBOUNDS_ERROR = 8, /**< Trying to access the index that is out of bounds */
U_PARSE_ERROR = 9, /**< Equivalent to Java ParseException */
U_INVALID_CHAR_FOUND = 10, /**< Character conversion: Unmappable input sequence. In other APIs: Invalid character. */
U_TRUNCATED_CHAR_FOUND = 11, /**< Character conversion: Incomplete input sequence. */
U_ILLEGAL_CHAR_FOUND = 12, /**< Character conversion: Illegal input sequence/combination of input units. */
U_INVALID_TABLE_FORMAT = 13, /**< Conversion table file found, but corrupted */
U_INVALID_TABLE_FILE = 14, /**< Conversion table file not found */
U_BUFFER_OVERFLOW_ERROR = 15, /**< A result would not fit in the supplied buffer */
U_UNSUPPORTED_ERROR = 16, /**< Requested operation not supported in current context */
U_RESOURCE_TYPE_MISMATCH = 17, /**< an operation is requested over a resource that does not support it */
U_ILLEGAL_ESCAPE_SEQUENCE = 18, /**< ISO-2022 illlegal escape sequence */
U_UNSUPPORTED_ESCAPE_SEQUENCE = 19, /**< ISO-2022 unsupported escape sequence */
U_NO_SPACE_AVAILABLE = 20, /**< No space available for in-buffer expansion for Arabic shaping */
U_CE_NOT_FOUND_ERROR = 21, /**< Currently used only while setting variable top, but can be used generally */
U_PRIMARY_TOO_LONG_ERROR = 22, /**< User tried to set variable top to a primary that is longer than two bytes */
U_STATE_TOO_OLD_ERROR = 23, /**< ICU cannot construct a service from this state, as it is no longer supported */
U_TOO_MANY_ALIASES_ERROR = 24, /**< There are too many aliases in the path to the requested resource.
It is very possible that a circular alias definition has occured */
U_ENUM_OUT_OF_SYNC_ERROR = 25, /**< UEnumeration out of sync with underlying collection */
U_INVARIANT_CONVERSION_ERROR = 26, /**< Unable to convert a UChar* string to char* with the invariant converter. */
U_INVALID_STATE_ERROR = 27, /**< Requested operation can not be completed with ICU in its current state */
U_COLLATOR_VERSION_MISMATCH = 28, /**< Collator version is not compatible with the base version */
U_USELESS_COLLATOR_ERROR = 29, /**< Collator is options only and no base is specified */
U_NO_WRITE_PERMISSION = 30, /**< Attempt to modify read-only or constant data. */
U_STANDARD_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for standard errors */
/*
* the error code range 0x10000 0x10100 are reserved for Transliterator
*/
U_BAD_VARIABLE_DEFINITION=0x10000,/**< Missing '</p> or duplicate variable name */
U_PARSE_ERROR_START = 0x10000, /**< Start of Transliterator errors */
U_MALFORMED_RULE, /**< Elements of a rule are misplaced */
U_MALFORMED_SET, /**< A UnicodeSet pattern is invalid*/
U_MALFORMED_SYMBOL_REFERENCE, /**< UNUSED as of ICU 2.4 */
U_MALFORMED_UNICODE_ESCAPE, /**< A Unicode escape pattern is invalid*/
U_MALFORMED_VARIABLE_DEFINITION, /**< A variable definition is invalid */
U_MALFORMED_VARIABLE_REFERENCE, /**< A variable reference is invalid */
U_MISMATCHED_SEGMENT_DELIMITERS, /**< UNUSED as of ICU 2.4 */
U_MISPLACED_ANCHOR_START, /**< A start anchor appears at an illegal position */
U_MISPLACED_CURSOR_OFFSET, /**< A cursor offset occurs at an illegal position */
U_MISPLACED_QUANTIFIER, /**< A quantifier appears after a segment close delimiter */
U_MISSING_OPERATOR, /**< A rule contains no operator */
U_MISSING_SEGMENT_CLOSE, /**< UNUSED as of ICU 2.4 */
U_MULTIPLE_ANTE_CONTEXTS, /**< More than one ante context */
U_MULTIPLE_CURSORS, /**< More than one cursor */
U_MULTIPLE_POST_CONTEXTS, /**< More than one post context */
U_TRAILING_BACKSLASH, /**< A dangling backslash */
U_UNDEFINED_SEGMENT_REFERENCE, /**< A segment reference does not correspond to a defined segment */
U_UNDEFINED_VARIABLE, /**< A variable reference does not correspond to a defined variable */
U_UNQUOTED_SPECIAL, /**< A special character was not quoted or escaped */
U_UNTERMINATED_QUOTE, /**< A closing single quote is missing */
U_RULE_MASK_ERROR, /**< A rule is hidden by an earlier more general rule */
U_MISPLACED_COMPOUND_FILTER, /**< A compound filter is in an invalid location */
U_MULTIPLE_COMPOUND_FILTERS, /**< More than one compound filter */
U_INVALID_RBT_SYNTAX, /**< A "::id" rule was passed to the RuleBasedTransliterator parser */
U_INVALID_PROPERTY_PATTERN, /**< UNUSED as of ICU 2.4 */
U_MALFORMED_PRAGMA, /**< A 'use' pragma is invlalid */
U_UNCLOSED_SEGMENT, /**< A closing ')' is missing */
U_ILLEGAL_CHAR_IN_SEGMENT, /**< UNUSED as of ICU 2.4 */
U_VARIABLE_RANGE_EXHAUSTED, /**< Too many stand-ins generated for the given variable range */
U_VARIABLE_RANGE_OVERLAP, /**< The variable range overlaps characters used in rules */
U_ILLEGAL_CHARACTER, /**< A special character is outside its allowed context */
U_INTERNAL_TRANSLITERATOR_ERROR, /**< Internal transliterator system error */
U_INVALID_ID, /**< A "::id" rule specifies an unknown transliterator */
U_INVALID_FUNCTION, /**< A "&fn()" rule specifies an unknown transliterator */
U_PARSE_ERROR_LIMIT, /**< The limit for Transliterator errors */
/*
* the error code range 0x10100 0x10200 are reserved for formatting API parsing error
*/
U_UNEXPECTED_TOKEN=0x10100, /**< Syntax error in format pattern */
U_FMT_PARSE_ERROR_START=0x10100, /**< Start of format library errors */
U_MULTIPLE_DECIMAL_SEPARATORS, /**< More than one decimal separator in number pattern */
U_MULTIPLE_DECIMAL_SEPERATORS = U_MULTIPLE_DECIMAL_SEPARATORS, /**< Typo: kept for backward compatibility. Use U_MULTIPLE_DECIMAL_SEPARATORS */
U_MULTIPLE_EXPONENTIAL_SYMBOLS, /**< More than one exponent symbol in number pattern */
U_MALFORMED_EXPONENTIAL_PATTERN, /**< Grouping symbol in exponent pattern */
U_MULTIPLE_PERCENT_SYMBOLS, /**< More than one percent symbol in number pattern */
U_MULTIPLE_PERMILL_SYMBOLS, /**< More than one permill symbol in number pattern */
U_MULTIPLE_PAD_SPECIFIERS, /**< More than one pad symbol in number pattern */
U_PATTERN_SYNTAX_ERROR, /**< Syntax error in format pattern */
U_ILLEGAL_PAD_POSITION, /**< Pad symbol misplaced in number pattern */
U_UNMATCHED_BRACES, /**< Braces do not match in message pattern */
U_UNSUPPORTED_PROPERTY, /**< UNUSED as of ICU 2.4 */
U_UNSUPPORTED_ATTRIBUTE, /**< UNUSED as of ICU 2.4 */
U_ARGUMENT_TYPE_MISMATCH, /**< Argument name and argument index mismatch in MessageFormat functions */
U_DUPLICATE_KEYWORD, /**< Duplicate keyword in PluralFormat */
U_UNDEFINED_KEYWORD, /**< Undefined Plural keyword */
U_DEFAULT_KEYWORD_MISSING, /**< Missing DEFAULT rule in plural rules */
U_DECIMAL_NUMBER_SYNTAX_ERROR, /**< Decimal number syntax error */
U_FMT_PARSE_ERROR_LIMIT, /**< The limit for format library errors */
/*
* the error code range 0x10200 0x102ff are reserved for Break Iterator related error
*/
U_BRK_INTERNAL_ERROR=0x10200, /**< An internal error (bug) was detected. */
U_BRK_ERROR_START=0x10200, /**< Start of codes indicating Break Iterator failures */
U_BRK_HEX_DIGITS_EXPECTED, /**< Hex digits expected as part of a escaped char in a rule. */
U_BRK_SEMICOLON_EXPECTED, /**< Missing ';' at the end of a RBBI rule. */
U_BRK_RULE_SYNTAX, /**< Syntax error in RBBI rule. */
U_BRK_UNCLOSED_SET, /**< UnicodeSet witing an RBBI rule missing a closing ']'. */
U_BRK_ASSIGN_ERROR, /**< Syntax error in RBBI rule assignment statement. */
U_BRK_VARIABLE_REDFINITION, /**< RBBI rule $Variable redefined. */
U_BRK_MISMATCHED_PAREN, /**< Mis-matched parentheses in an RBBI rule. */
U_BRK_NEW_LINE_IN_QUOTED_STRING, /**< Missing closing quote in an RBBI rule. */
U_BRK_UNDEFINED_VARIABLE, /**< Use of an undefined $Variable in an RBBI rule. */
U_BRK_INIT_ERROR, /**< Initialization failure. Probable missing ICU Data. */
U_BRK_RULE_EMPTY_SET, /**< Rule contains an empty Unicode Set. */
U_BRK_UNRECOGNIZED_OPTION, /**< !!option in RBBI rules not recognized. */
U_BRK_MALFORMED_RULE_TAG, /**< The {nnn} tag on a rule is mal formed */
U_BRK_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for Break Iterator failures */
/*
* The error codes in the range 0x10300-0x103ff are reserved for regular expression related errrs
*/
U_REGEX_INTERNAL_ERROR=0x10300, /**< An internal error (bug) was detected. */
U_REGEX_ERROR_START=0x10300, /**< Start of codes indicating Regexp failures */
U_REGEX_RULE_SYNTAX, /**< Syntax error in regexp pattern. */
U_REGEX_INVALID_STATE, /**< RegexMatcher in invalid state for requested operation */
U_REGEX_BAD_ESCAPE_SEQUENCE, /**< Unrecognized backslash escape sequence in pattern */
U_REGEX_PROPERTY_SYNTAX, /**< Incorrect Unicode property */
U_REGEX_UNIMPLEMENTED, /**< Use of regexp feature that is not yet implemented. */
U_REGEX_MISMATCHED_PAREN, /**< Incorrectly nested parentheses in regexp pattern. */
U_REGEX_NUMBER_TOO_BIG, /**< Decimal number is too large. */
U_REGEX_BAD_INTERVAL, /**< Error in {min,max} interval */
U_REGEX_MAX_LT_MIN, /**< In {min,max}, max is less than min. */
U_REGEX_INVALID_BACK_REF, /**< Back-reference to a non-existent capture group. */
U_REGEX_INVALID_FLAG, /**< Invalid value for match mode flags. */
U_REGEX_LOOK_BEHIND_LIMIT, /**< Look-Behind pattern matches must have a bounded maximum length. */
U_REGEX_SET_CONTAINS_STRING, /**< Regexps cannot have UnicodeSets containing strings.*/
U_REGEX_OCTAL_TOO_BIG, /**< Octal character constants must be <= 0377. */
U_REGEX_MISSING_CLOSE_BRACKET, /**< Missing closing bracket on a bracket expression. */
U_REGEX_INVALID_RANGE, /**< In a character range [x-y], x is greater than y. */
U_REGEX_STACK_OVERFLOW, /**< Regular expression backtrack stack overflow. */
U_REGEX_TIME_OUT, /**< Maximum allowed match time exceeded */
U_REGEX_STOPPED_BY_CALLER, /**< Matching operation aborted by user callback fn. */
U_REGEX_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for regexp errors */
/*
* The error code in the range 0x10400-0x104ff are reserved for IDNA related error codes
*/
U_IDNA_PROHIBITED_ERROR=0x10400,
U_IDNA_ERROR_START=0x10400,
U_IDNA_UNASSIGNED_ERROR,
U_IDNA_CHECK_BIDI_ERROR,
U_IDNA_STD3_ASCII_RULES_ERROR,
U_IDNA_ACE_PREFIX_ERROR,
U_IDNA_VERIFICATION_ERROR,
U_IDNA_LABEL_TOO_LONG_ERROR,
U_IDNA_ZERO_LENGTH_LABEL_ERROR,
U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR,
U_IDNA_ERROR_LIMIT,
/*
* Aliases for StringPrep
*/
U_STRINGPREP_PROHIBITED_ERROR = U_IDNA_PROHIBITED_ERROR,
U_STRINGPREP_UNASSIGNED_ERROR = U_IDNA_UNASSIGNED_ERROR,
U_STRINGPREP_CHECK_BIDI_ERROR = U_IDNA_CHECK_BIDI_ERROR,
/*
* The error code in the range 0x10500-0x105ff are reserved for Plugin related error codes
*/
U_PLUGIN_ERROR_START=0x10500, /**< Start of codes indicating plugin failures */
U_PLUGIN_TOO_HIGH=0x10500, /**< The plugin's level is too high to be loaded right now. */
U_PLUGIN_DIDNT_SET_LEVEL, /**< The plugin didn't call uplug_setPlugLevel in response to a QUERY */
U_PLUGIN_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for plugin errors */
U_ERROR_LIMIT=U_PLUGIN_ERROR_LIMIT /**< This must always be the last value to indicate the limit for UErrorCode (last error code +1) */
} UErrorCode;
|
編碼的識(shí)別
來自ByVoid 郭家寶
為什么用universalchardet?其實(shí)編碼自動(dòng)識(shí)別的解決方案不止一個(gè),有icu提供的解決方案,IE也有API,還有已經(jīng)在很多Linux發(fā)行版中的enca。之所以用universalchardet,是因?yàn)樗亲詈线m的。IE的API不能跨平臺(tái),icu實(shí)現(xiàn)太龐大,enca是GPL(注意不是LGPL),使用它意味著我也要讓我的所有源碼使用GPL,而不是更加開放的Apache。universalchardet是MPL的,和LGPL差不多寬松,使用它是沒有問題的。我非常不喜歡以GPL發(fā)布的函數(shù)庫,這給開發(fā)者的限制太大了。
轉(zhuǎn)自:http://blog.csdn.net/wangjieest/article/details/8097035
|