介紹Unicode的編碼方式和實現方式
大概來說,Unicode 編碼系統可分為編碼方式和實現方式兩個層次。
編碼方式Unicode是國際組織制定的可以容納世界上所有文字和符號的字元編碼方案。Unicode用數字0-0x10FFFF來對映這些字元,最多可以容納1114112個字元,或者說有1114112個碼位。碼位就是可以分配給字元的數字。UTF-8、UTF-16、UTF-32都是將數字轉換到程式資料的編碼方案。
通用字符集(Universal Character Set,UCS)是由ISO制定的ISO 10646(或稱ISO/IEC 10646)標準所定義的標準字符集。UCS-2用兩個位元組編碼,UCS-4用4個位元組編碼。
UCS-4根據最高位為0的最高位元組分成2^7=128個group。每個group再根據次高位元組分為256個平面(plane)。每個平面根據第3個位元組分為256行 (row),每行有256個碼位(cell)。group 0的平面0被稱作BMP(Basic Multilingual Plane)。將UCS-4的BMP去掉前面的兩個零位元組就得到了UCS-2。每個平面有2^16=65536個碼位。Unicode計劃使用了17個平面,一共有17*65536=1114112個碼位。在Unicode 5.0.0版本中,已定義的碼位只有238605個,分佈在平面0、平面1、平面2、平面14、平面15、平面16。其中平面15和平面16上只是定義了兩個各佔65534個碼位的專用區(Private Use Area),分別是0xF0000-0xFFFFD和0x100000-0x10FFFD。所謂專用區,就是保留給大家放自定義字元的區域,可以簡寫為PUA。
實現方式
BYTE data_utf8[] = {0xE6, 0xB1, 0x89, 0xE5, 0xAD, 0x97}; // UTF-8編碼
WORD data_utf16[] = {0x6c49, 0x5b57}; // UTF-16編碼
DWORD data_utf32[] = {0x6c49, 0x5b57}; // UTF-32編碼
這裡用BYTE、WORD、DWORD分別表示無符號8位整數,無符號16位整數和無符號32位整數。UTF-8、UTF-16、UTF-32分別以BYTE、WORD、DWORD作為編碼單位。“漢字”的UTF-8編碼需要6個位元組。“漢字”的UTF-16編碼需要兩個WORD,大小是4個位元組。“漢字”的UTF-32編碼需要兩個DWORD,大小是8個位元組。根據位元組序的不同,UTF-16可以被實現為UTF-16LE或UTF-16BE,UTF-32可以被實現為UTF-32LE或UTF-32BE。下面介紹UTF-8、UTF-16、UTF-32、位元組序和BOM。
UTF-8
UTF-8以位元組為單位對Unicode進行編碼。從Unicode到UTF-8的編碼方式如下:
Unicode編碼(16進位制) ║ UTF-8 位元組流(二進位制)
000000 - 00007F ║ 0xxxxxxx
000080 - 0007FF ║ 110xxxxx 10xxxxxx
000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx
010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8的特點是對不同範圍的字元使用不同長度的編碼。對於0x00-0x7F之間的字元,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是4個位元組。從上表可以看出,4位元組模板有21個x,即可以容納21位二進位制數字。Unicode的最大碼位0x10FFFF也只有21位。
例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3位元組模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進位制是:0110 1100 0100 1001, 用這個位元流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。
例2:Unicode編碼0x20C30在0x010000-0x10FFFF之間,使用用4位元組模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。將0x20C30寫成21位二進位制數字(不足21位就在前面補0):0 0010 0000 1100 0011 0000,用這個位元流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。