官术网_书友最值得收藏!

1.3.2 Unicode與UTF-8

上一節(jié)介紹了GB編碼,與之對應(yīng),各國也有各自的文本編碼標準。圖1-14顯示了各種編碼標準的衍生關(guān)系。為了有一種統(tǒng)一的編碼標準,1990年,聯(lián)合國經(jīng)濟社會文化組織(ECOSOC)開始制定Unicode編碼標準。

img

圖1-14 各種編碼標準的衍生關(guān)系

通過Unicode官網(wǎng)可以看到,截至2022年9月13日,共發(fā)布了15個版本。

Unicode有1 114 112(0x110000)個碼位,分為17個字符平面,每個平面有65 536個碼位。

Unicode 7.0標準共收錄字符112 956個,其中漢字74 616個。

對于同一個Unicode碼位,通常有3種編碼方式:UTF-8、UTF-16、UTF-32。UTF-32編碼總是使用4字節(jié),相鄰的編碼具備連續(xù)性。UTF-16編碼總是使用2字節(jié),且在0平面與UTF-32相等。

Windows平臺通常使用UTF-16編碼,而macOS平臺通常使用UTF-32編碼。

0平面為基本位平面(Basic Multilingual Plane,BMP),碼位從0x0000到0xFFFF。

Unicode為亞洲文字保留了CJK(Chinese Japanese Korean)區(qū)域,從0平面的0x4E00開始,共包含20 912個漢字。還有5個A~E的擴展區(qū)域,其中CJK A擴展區(qū)域位于0平面,從0x3400開始,擴展區(qū)域B~E位于2平面。

在0平面的0xD800和0xDC00開始的地方,各保留了1 024個碼位,被稱為UTF-16替代區(qū)(UTF-16 Surrogate Codec),用來轉(zhuǎn)義1~16平面中的字符。這樣大于2字節(jié)的字符,也能在UTF-16編碼下進行表示。

1平面為補充位平面(Supplementary Multilingual Plane,SMP),碼位從0x10000到0x1FFFF。

平面3~14中的很多碼位都尚待分配。

最后的15、16平面為私人使用區(qū),用戶可以自行定義,被稱為PUA(Private Use Area)-A、PUA-B。

在Windows平臺上,可以使用如下兩個API進行Unicode與GB編碼之間的互轉(zhuǎn)。

img

在UNIX平臺上,我們通常使用libiconv開源庫來完成字符集之間的轉(zhuǎn)換。

UTF-8編碼

Unicode用來表示全球的文本是足夠的,但它的問題是,當它用來表示英文的時候,太浪費了。

英文字符只需要128個碼位就足夠了,于是1992年,UTF-8編碼被UNIX系統(tǒng)的發(fā)明人Ken Thompson發(fā)明出來。

UTF-8編碼使用1~6個變長字節(jié)來表示1個字符。

當使用1字節(jié)時,它與ASCII碼完全一致,即0x00~0x7F,形如二進制0xxxxxxx,這里字母x代表0或1。

當使用2字節(jié)時,可以表示0x80~0x07FF的碼位,形如110xxxxx 10xxxxxx可以表示8~11比特。

當使用3字節(jié)時,可以表示0x0800~0xFFFF,形如1110xxxx 10xxxxxx 10xxxxxx,可以表示12~16比特,這能表示所有2字節(jié)的編碼。由于常用漢字都位于0平面的CJK和CJK A中,因此大多數(shù)漢字也能用3個UTF-8編碼表示。

當使用4字節(jié)時,其位序列為11110xxx 10xxxxxx 10xxxxxx 10xxxxxx,可以表示21比特,表示范圍是0x10000~0x1FFFF,這是Unicode 6.1的標準。

其余更大的UTF32字符,則使用5字節(jié)或6字節(jié)的UTF-8編碼。

Unicode的文件,通常會在最前面加上3字節(jié)的BOM(Byte Order Mark)頭,來表示文本的編碼與字節(jié)序。

對于UTF-8編碼,BOM通常為0xEF 0xBB 0xBF。為了能讓C++源碼跨平臺顯示與編譯,我們的.h/.cpp文件都必須加上UTF-8的BOM頭。

Windows平臺上提供的字符集轉(zhuǎn)換API也可以用于UTF-8編碼的轉(zhuǎn)換。

但由于UTF-8編碼相對容易清晰,自己實現(xiàn)一套UTF-8與UTF-16的轉(zhuǎn)換函數(shù)也是很方便的。

以下函數(shù)實現(xiàn)了對一個2字節(jié)字符的UTF-8編碼,同時返回其需要的UTF-8字節(jié)數(shù)。

img

讀者可以將上述代碼作為參考,并實現(xiàn)對應(yīng)UTF-32字符的編解碼函數(shù),以及對一個連續(xù)Unicode字符串的UTF-8轉(zhuǎn)換[15]

下一節(jié)將展示一個顯示文本對應(yīng)編碼的工具。

主站蜘蛛池模板: 茂名市| 凉城县| 胶南市| 甘孜县| 平武县| 巨鹿县| 辽宁省| 来凤县| 平远县| 荣成市| 行唐县| 丰宁| 沁阳市| 微山县| 云阳县| 新津县| 炉霍县| 长沙市| 溧水县| 新乡县| 隆昌县| 延津县| 孟津县| 武陟县| 宜兴市| 南川市| 文水县| 桃园市| 凤翔县| 福州市| 麦盖提县| 富裕县| 桦南县| 石阡县| 松阳县| 北碚区| 延边| 华安县| 竹北市| 玉环县| 纳雍县|