从程序员的观点看 汉字国标与Unicode
工作中時常接觸到一些于編碼相關的術語,比如ASCII,Unicode,UTF-8,UTF-16 ,UTF-32,在C++編程中經常會遇到char,wchar_t,std::string,std::wstring,std::cout,std::wcout,CString,TCHAR。這么多的術語到底有什么樣的關系呢?本文試圖理清這些概念,以及如何應用他們。
ASCII與漢字國標
ASCII (American Standard Code for Information Interchange) 是美國標準信息交換碼。它是一套基于拉丁字母的編碼系統,主要用于顯示英語和西歐語言。ASCII使用單字節進行存儲,其中保留了最高位,因此可以存儲128個字符,因此這種編碼標準定義了33個控制字符和95個打印字符(包括空格)。
GB 2312或GB 2312-80是一個簡體中文字符集的中國國家標準,全稱為《信息交換用漢字編碼字符集·基本集》,又稱為GB0。GB2312編碼通行于中國大陸。中國大陸幾乎所有的中文系統和國際化的軟件都支持GB 2312。GB 2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。對于人名、古漢語等方面出現的罕用字,GB 2312不能處理,因此出現了GBK。
GBK是GB2312的一個擴展,使用了GB2312中未使用的一些代碼點。微軟在Win95中以Codepage936實現了GBK。后來國家相關部門又對GBK擴展形成了GBK1.0,它僅僅是GB 2312到GB 13000之間的過渡方案。
GB 13000,中華人民共和國國家標準的國家標準代碼之一,全稱 GB 13000.1-93《信息技術 通用多八位編碼字符集(UCS)第一部分:體系結構與基本多文種平面》。此標準等同采用國際標準化組織 ISO/IEC 10646.1:1993《信息技術 通用多八位編碼字符集(UCS)第一部分:體系結構與基本多文種平面》。GB 13000的字符集包含20,902個漢字。
GB 18030,全稱:國家標準GB 18030-2005《信息技術 中文編碼字符集》,是中華人民共和國現時最新的內碼字集,是GB 18030-2000《信息技術 信息交換用漢字編碼字符集 基本集的擴充》的修訂版。與GB 2312-1980完全兼容,與GBK基本兼容,支持GB 13000及Unicode的全部統一漢字,共收錄漢字70244個。GB 18030主要有以下特點:采用多字節編碼,每個字可以由1個、2個或4個字節組成。編碼空間龐大,最多可定義161萬個字符。支持中國國內少數民族的文字,不需要動用造字區。
Unicode 編碼
通用字符集(Universal Character Set,UCS)是由ISO制定的編碼方式,采用4字節編碼。目前廣泛應用的 Unicode 版本對應于 UCS-2,使用2字節的編碼空間。UCS-2定義了字符和2字節編碼的映射。這樣理論上一共最多可以表示 216 即 65536個字符。基本滿足各種語言的使用。實際上UCS-2尚未填滿這16位的編碼,保留了大量空間作為特殊使用或將來擴展。USC-2構成基本多文種平面(Basic Multilingual Plane,簡稱 BMP)。
一個字符的 UCS編碼(Unicode 編碼)是確定的。但是在實際傳輸過程中,由于不同系統平臺的設計不一定一致,以及出于節省空間的目的,對 Unicode 編碼的實現方式有所不同。存儲UCS定義編碼的方式被稱為Unicode轉換格式(Unicode Translation Format,簡稱為 UTF),UTF把字符的編碼(code point)轉化為字節流,根據轉化方式的不同產生了UTF-8,UTF-16等。
例如,如果一個僅包含基本7位ASCII字符的 Unicode 文件,如果每個字符都使用2字節的原 Unicode 編碼傳輸,其第一字節的8位始終為0。這就造成了比較大的浪費。對于這種情況,可以使用 UTF-8 編碼,這是一種變長編碼,它將基本7位ASCII字符仍用7位編碼表示,占用一個字節(首位補0)。而遇到與其他 Unicode 字符混合的情況,將按一定算法轉換,每個字符使用1-3個字節編碼,并利用首位為0或1進行識別。這樣對以7位ASCII字符為主的西文文檔就大大節省了編碼長度(具體方案參見UTF-8)。
再如,如果直接使用與 Unicode 編碼一致(僅限于 BMP 字符)的 UTF-16 編碼,由于每個字符占用了兩個字節,在Macintosh (Mac)機和PC機上,對字節順序的理解是不一致的。這時同一字節流可能會被解釋為不同內容,如某字符為十六進制編碼4E59,按兩個字節拆分為4E和59,在Mac上讀取時是從低字節開始,那么在Mac OS會認為此4E59編碼為594E,找到的字符為「奎」,而在Windows上從高字節開始讀取,則編碼為 U+4E59 的字符為「乙」。就是說在Windows下以UTF-16編碼保存一個字符「乙」,在Mac OS里打開會顯示成「奎」。此類情況說明UTF-16的編碼順序若不加以人為定義就可能發生混淆,于是在 UTF-16 編碼實現方式中使用了大尾序(Big-Endian, 簡寫為UTF-16 BE)、小尾序(Little-Endian, 簡寫為UTF-16 LE)的概念,以及可附加的BOM(Byte Order Mark)解決方案,目前在PC機上的Windows系統和Linux系統對于UTF-16編碼默認使用UTF-16 LE。(具體方案參見UTF-16)。
此外 Unicode 的實現方式還包括 UTF-7、Punycode、CESU-8、SCSU、UTF-32等,這些實現方式有些僅在一定的國家和地區使用,有些則屬于未來的規劃方式。目前通用的實現方式是 UTF-16小尾序(BOM)、UTF-16大尾序(BOM)和 UTF-8。
C/C++語言對Unicode的支持
C語言中的wchar_t可以用來部分提供對Unicode的支持,但是C語言并未定義wchar_t的大小,因此wchar_t的大小是與編譯器相關的。在Win32平臺wchar_t是16位,可以用來存儲UTF-16 code unit;在Unix平臺wchar_t是32位的用來存儲UTF-32 code unit。Std::out用來輸出char和std::string,std::wcout用來輸出wchar_t和std::wcout 。
因此如下代碼在Windows下可以輸出部分CJK漢字,當然此程序需要以UNICODE編譯:
void CtestUnicodeDlgDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
TCHAR tch = 0x4E00;
std::wstring text ;
for( ;tch <= 0x9FC3; ++tch){
text += tch;
}
output.SetWindowTextW(text.c_str());
}
VC編譯器會根據是否定義了UNICODE宏來決定把TCHAR翻譯成char或wchar_t,更多與此相關信息請參閱Windows核心編程第2章,UNICODE
以下代碼則可以輸出GBK漢字:
C++0x標準將添加新的類型:std::char16_t和std::char32_t來支持Unicode,他們可以分別用來存儲UTF-16和UTF-32字符串,此外可以使用’u’和’U’來定義常量字符串。
Std::char16_t utf16[] = u”UTF16”;
Std::char32_t utf32[] = U”UTF32”;
同時還有typedef std::basic_stringu16string
typedef std::basic_stringu32string
當然可以使用一些第三方庫比如:i18n。
Windows對漢字與Unicode的支持
Windows對本地編碼的實現稱為Code Page。比如說Windows以code page 54936實現了GB18030(code page 936實現了GBK)。Windows XP原生支持GB18030, 而Windows2000需要安裝GB18030支持包,因此使用Win32API (MultiByteToWideChar和WideCharToMultiByte)可以實現GB18030和UTF-16之間的轉換。
在Windows XP操作系統附帶的記事本中,「另存為」對話框可以選擇的四種編碼方式除去非 Unicode 編碼的ANSI(對于英文系統即ASCII編碼,中文系統則為GB18030) 外,其余三種為「Unicode」(對應UTF-16 LE)、「Unicode big endian」(對應UTF-16 BE)和「UTF-8」。
非Unicode程序在其它語言的操作系統上會出現亂碼,原因就是沒有設置local,比如英文xp系統:
另外可以使用AppLocal同時以不同的Local運行多個程序,Windows 控制臺不支持Unicode。
Linux對漢字與Unicode的支持
Linux 系統通過系統local 提供對區域編碼的支持,比如:zh_CN.UTF-8。Local的名字采用以下的形式:language(_territory)(.encoding)(@modifier)。Linux通過一系列的環境變量提供對多編碼的支持,如果系統只需要使用一種local只需要設置環境變量LANG即可。更多信息請參考這里:http://www.linux.com/archive/feature/53781
參考:
維基百科:http://en.wikipedia.org/wiki/Main_Page
MSDN: http://msdn.microsoft.com/en-us/default.aspx
http://www.linux.com/archive/
Unicode標準化組織:http://unicode.org
C++標準委員會:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/
總結
以上是生活随笔為你收集整理的从程序员的观点看 汉字国标与Unicode的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FPGA入门 Xilinx暑期学校学习D
- 下一篇: 《左耳听风-高效学习篇》阅读笔记