Unicode碼和Emoji表情

一.ASCII碼到Unicode

ASCII碼是7位,它將英文字母,數(shù)字0-9以及一些標(biāo)點(diǎn)符號和控制字符映射為0-127這些整型。

由于8位的空間對于各國文字遠(yuǎn)遠(yuǎn)不夠,因此Unicode碼誕生。
起初,Unicode被設(shè)計(jì)為16位,提供65536個字符的空間。當(dāng)時人們認(rèn)為這已經(jīng)大到足夠編碼世界上現(xiàn)代文本里所有的文字和字符了。

考慮到歷史上的文字和比較少使用到的日本中國漢字,Unicode編碼擴(kuò)展到21位。

二.Unicode編碼空間

Unicode的基本元素被稱作編碼點(diǎn)(Code Point)。編碼點(diǎn)通過數(shù)字來區(qū)分,通常寫成16進(jìn)制的形式再加上前綴"U+",所有編碼點(diǎn)組成的集合被稱作編碼空間(Code Space)。

Unicode的編碼空間包含1114112個編碼點(diǎn)。然而,其中只有128237個編碼點(diǎn)(12%的編碼空間被賦值),目前,還有很多空間用來增長,同時,Unicode還保留了另外的137468字符作為"自用"空間,這些字符沒有標(biāo)準(zhǔn)的含義,可以被個人應(yīng)用所使用。

為了對編碼空間的布局有個了解,把它可視化會比較直觀。下面是整個編碼空間的布局,一個像素代表一個編碼點(diǎn)。使用小方塊表示以保證視覺的一致性;每個小方塊是16*16=256個編碼點(diǎn),每個大方塊是一個面有65536個編碼點(diǎn),總共加起來有17個面板。

面板.png
  • 白色空間表示未使用
  • 藍(lán)色表示已經(jīng)使用
  • 綠色表示自用區(qū)域
  • 小的紅色表示代理區(qū)

第一個面板被稱作(基本多語言面板BMP)。BMP包含現(xiàn)代文本所需的基本所有字符,包括拉丁文、斯拉夫文、希臘文、漢字(中國),日文、朝鮮文、阿拉伯文、希伯來文、梵文(印度)等。這個面板就是最長Unicode設(shè)計(jì)所占用的空間(16位,65536個字符).后來擴(kuò)展到現(xiàn)在這個規(guī)模,然而,大部分現(xiàn)代字符在BMP的范圍內(nèi)。

第二個面板則包括歷史上的文字,比如蘇美爾楔形文字和埃及象形文字以及emoji表情.

第三個面板包含了一大塊不常用的歷史上的漢字字符。

剩下的面板,除了倒數(shù)第三個面板中有一小部分被用作格式化字符;倒數(shù)兩個面板全部保留自用。

為了和以前的ASCII兼容,Unicode128個字符就是ASCII的拷貝.

三. UTF8,UTF16,UTF32

使用頻率圖.png

這是unicode編碼面板中的前三個面板的使用頻率圖,可以看出使用頻率最高的絕大多數(shù)分部在BMP內(nèi),零散的來自第二三個面板。第二個面板下高頻率使用的字符則是部分emoji表情。

為了解決unicode編碼占據(jù)的內(nèi)存問題,unicode就有了幾個緊湊的編碼。

注意
UTF是Unicode Transformation Format的縮寫,意為Unicode轉(zhuǎn)換格式
其中,UTF-8是UTF中最常用的轉(zhuǎn)換格式,是UNICODE的一種變長字符編碼。

UTF-32

32位整數(shù)編碼,很少被用來存儲,因?yàn)樘加脙?nèi)存和存儲空間。

UTF-8/UTF-16
這兩個編碼是可變長編碼,分別由8-bit16-bit為一個單元組成,這些方案中下標(biāo)值較小的編碼點(diǎn)占用的字節(jié)數(shù)也少,會節(jié)省不少內(nèi)存。

1.UTF-8

UTF-8中,每個編碼點(diǎn)依據(jù)下標(biāo)值,被存儲為14個字節(jié)。

越是常用的字符,字節(jié)越短,最前面的128個字符,只使用一個字節(jié)表示,與ASCII碼完全相同。

image.png

UTF8有以下幾個好處:

  • 對于很常見的西文字符,采用這種編碼方式也不會浪費(fèi)內(nèi)存。

  • 由于UTF-8 是基于 8 位的碼元的,因此它并不需要關(guān)心字節(jié)順序。

  • 任何已經(jīng)是 ASCII 編碼的字符串和文件無需轉(zhuǎn)換就可以被 UTF-8 識別。

  • 大量的廣泛使用的編程慣例——比如 NULL 結(jié)尾,分隔符(n,t,’,’,”)等——在 UTF-8中也是可用的。

因?yàn)檫@些原因,UTF-8 成為存儲和交流 Unicode 文本方面的最佳編碼。它也已經(jīng)是文件格式、網(wǎng)絡(luò)協(xié)議以及 Web API 領(lǐng)域里事實(shí)上的標(biāo)準(zhǔn)了。

2.UTF16

UTF-16編碼介于UTF-32UTF-8之間,同時結(jié)合了定長和變長兩種編碼方法的特點(diǎn)。

它的編碼規(guī)則很簡單:基本平面的字符占用2個字節(jié),輔助平面的字符占用4個字節(jié)。也就是說,UTF-16的編碼長度要么是2個字節(jié)(U+0000U+FFFF),要么是4個字節(jié)(U+010000U+10FFFF)。

于是這里就存在一個問題,當(dāng)我們遇到兩個字符,怎么看出它本身是一個字符,還是需要跟其他兩個字節(jié)放在一起解讀。

我們可以從基本平面看到,從U+D800U+DFFF是一個空段,即這些碼點(diǎn)不對應(yīng)任何字符。因此,這個空段可以用來映射輔助平面的字符。

具體來說,輔助平面的字符位共有2^20個,也就是說,對應(yīng)這些字符至少需要20個二進(jìn)制位。UTF-16將這20位拆成兩半,前10位映射在U+D800U+DBFF(空間大小2^10),稱為高位(H),后10位映射在U+DC00U+DFFF(空間大小2^10),稱為低位(L)。這意味著,一個輔助平面的字符,被拆成兩個基本平面的字符表示。

所以,當(dāng)我們遇到兩個字節(jié),發(fā)現(xiàn)它的碼點(diǎn)在U+D800U+DBFF之間,就可以斷定,緊跟在后面的兩個字節(jié)的碼點(diǎn),應(yīng)該在U+DC00U+DFFF之間,這四個字節(jié)必須放在一起解讀。

3. UTF-32

UTF-32,將Unicode的每個碼點(diǎn)使用4個字節(jié)表示,字節(jié)內(nèi)容一一對應(yīng)碼點(diǎn)。比如,碼點(diǎn)0就用4個字節(jié)的0表示,碼點(diǎn)597D就在前面加兩個字節(jié)的0。

U+0000 = 0x0000 0000

U+597D = 0x0000 597D

UTF-32的優(yōu)點(diǎn)在于,轉(zhuǎn)換規(guī)則簡單,查找效率高,缺點(diǎn)在于浪費(fèi)空間,同樣內(nèi)容的英語文本,會比ASCII碼大四倍。

這個缺點(diǎn)導(dǎo)致實(shí)際上沒有人使用這種編碼方法。

四.組合字符

Unicode包含一個系統(tǒng),可以合并多個編碼點(diǎn),動態(tài)組合字符。此系統(tǒng)用這種方式增加靈活性,而不引起編碼點(diǎn)的巨大組合膨脹。

例如,帶重音的字符“á”會被表示成由兩個編碼點(diǎn)組成的字符串:U+0041 “A”拉丁大寫字母 a加上 U+0301 “??”組合尖音符號。這個字符串自動被渲染成單個字符:“á”。

如今,Unicode還包含許多 “預(yù)設(shè)的” 編碼點(diǎn),每個表示一個被使用過的組合,例如 U+00C1 “á” 帶銳音符的拉丁大寫字母AU+1EC7 “?”帶揚(yáng)抑符和下點(diǎn)的小寫拉丁字母 e。

Unicode 中,預(yù)設(shè)字符和動態(tài)組合系統(tǒng)并存。后果就是有多種方法表示同一個字符串——不同編碼點(diǎn)序列產(chǎn)生相同用戶可感知的字符。例如,我們之前看到的,表示字符 “á”,我們可以用一個編碼點(diǎn) U+00C1 ,也可以用兩個編碼點(diǎn) U+0041U+0301。要解決這個等值字符串的問題,Unicode 定義了幾種形式正規(guī)化方法。比如NFDNFC。

五.字符簇

Unicode包含多種情況,用戶認(rèn)為的一個"字符"事實(shí)上底下可能由多個編碼點(diǎn)組成。

Unicode使用"字位簇"的概念來表示這種情況,一個由一個或多個編碼點(diǎn)組成的字符串構(gòu)成一個"用戶感知的字符"。

部分的emojiunicode長度大于1的本質(zhì)原因是這些emoji是字符簇。

從這里我們可以知道emoji表情其實(shí)是由一個或多個編碼點(diǎn)組成的字符串,那我們要怎么判斷用戶輸入的是否為emoji表情,又或者判斷一個字符串中是否包含emoji表情呢。

具體詳見下一篇:

iOS 輸入框如何限制字符長度和emoji

六. 閱讀延伸

Unicode與JavaScript詳解
從Emoji的限制到Unicode編碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容