Unicode&UTF&碼點(diǎn)關(guān)系

轉(zhuǎn)自:https://cloud.tencent.com/developer/article/1470820

字符編碼

你是否認(rèn)為 ASCII 碼就是一個(gè)字符,一個(gè)字節(jié)就是一個(gè)字符,一個(gè)字符就是 8 比特?你是否認(rèn)為 UTF-8 就是用 8 比特表示一個(gè)字符葵擎?如果真的是這樣認(rèn)為這篇文章就很適合你蜡豹。

為什么要有編碼麸粮?

首先大家需要明確的是在計(jì)算機(jī)里所有的數(shù)據(jù)都是字節(jié)的形式存儲(chǔ)和處理的。我們需要字節(jié)來(lái)表示計(jì)算機(jī)里的信息镜廉,但是這些字節(jié)本身又是沒(méi)有任何意義的弄诲。我們需要對(duì)這些字節(jié)賦予實(shí)際的意義,制定各種編碼標(biāo)準(zhǔn)娇唯。

編碼模型

首先需要知道的是存在兩種編碼模型

簡(jiǎn)單字符集

在這種編碼模型里齐遵,一個(gè)字符集定義了這個(gè)字符集里包含什么字符,同時(shí)把每個(gè)字符如何對(duì)應(yīng)成計(jì)算機(jī)里的比特也進(jìn)行了定義塔插。例如 ASCII梗摇,在 ASCII 里直接定義了 A -> 0100 0001

現(xiàn)代編碼模型

在現(xiàn)代編碼模型里要知道一個(gè)字符如何映射成計(jì)算機(jī)里比特想许,需要經(jīng)過(guò)如下幾個(gè)步驟:

  1. 知道一個(gè)系統(tǒng)需要支持哪些字符伶授,這些字符的集合被稱為字符表(Character repertoire)

  2. 給字符表里的抽象字符編上一個(gè)數(shù)字,也就是字符集合到一個(gè)整數(shù)集合的映射伸刃。這種映射稱為編碼字符集(CCS:Coded Character Set), unicode 是屬于這一層的概念谎砾,unicode 跟計(jì)算機(jī)里的什么進(jìn)制啊沒(méi)有任何關(guān)系,它是完全數(shù)學(xué)的抽象的捧颅。

  3. 將 CCS 里字符對(duì)應(yīng)的整數(shù)轉(zhuǎn)換成有限長(zhǎng)度的比特值景图,便于以后計(jì)算機(jī)使用一定長(zhǎng)度的二進(jìn)制形式表示該整數(shù)。這個(gè)對(duì)應(yīng)關(guān)系被稱為字符編碼表(CEF:Character Encoding Form)UTF-8, UTF-16 都屬于這層碉哑。

  4. 對(duì)于 CEF 得到的比特值具體如何在計(jì)算機(jī)中進(jìn)行存儲(chǔ)挚币,傳輸亮蒋。因?yàn)榇嬖诖蠖诵《说膯?wèn)題,這就會(huì)跟具體的操作系統(tǒng)相關(guān)了妆毕。這種解決方案稱為字符編碼方案(CES:Character Encoding Scheme)慎玖。

平常我們所說(shuō)的編碼都在第三步的時(shí)候完成了,并沒(méi)有涉及到 CES。所以 CES 并不在本文的討論范圍之內(nèi)笛粘。 現(xiàn)在也許有人會(huì)想為什么要有現(xiàn)代的編碼模型趁怔?為什么在現(xiàn)在的編碼模型要拆分出這么多概念?直接像原始的編碼模型直接都規(guī)定好所有的信息不行嗎薪前?這些問(wèn)題在下文的編碼發(fā)展史中都會(huì)有所闡述润努。

編碼的發(fā)展史

ASCII

ASCII 出現(xiàn)在上個(gè)世紀(jì) 60 年代的美國(guó),ASCII 一共定義了 128 個(gè)字符示括,使用了一個(gè)字節(jié)的 7 位铺浇。定義的這些字符包括英文字母 A-Z,a-z垛膝,數(shù)字 0-9鳍侣,一些標(biāo)點(diǎn)符號(hào)和控制符號(hào)。在 Shell 里輸入man ASCII吼拥,可以看到完整的 ASCII 字符集倚聚。ASCII 采用的編碼模型是簡(jiǎn)單字符集,它直接定義了一個(gè)字符的比特值表示凿可。例如上文提到的A -> 0100 0001秉沼。也就是 ASCII 直接完成了現(xiàn)代編碼模型的前三步工作。 在英語(yǔ)系國(guó)家里 ASCII 標(biāo)準(zhǔn)很完美矿酵。但是不要忘了世界上可有好幾千種語(yǔ)言,這些語(yǔ)言里不僅只有這些符號(hào)啊矗积。如果使用這些語(yǔ)言的人也想使用計(jì)算機(jī)全肮,ASCII 就遠(yuǎn)遠(yuǎn)不夠了。所以到這里編碼進(jìn)入了混亂的時(shí)代棘捣。

混亂時(shí)代

人們知道計(jì)算機(jī)的一個(gè)字節(jié)是 8 位辜腺,可以表示 256 個(gè)字符。ASCII 卻只使用了 7 位乍恐,所以人們決定把剩余的一位也利用起來(lái)评疗。這時(shí)問(wèn)題出現(xiàn)了,人們對(duì)于已經(jīng)規(guī)定好的 128 個(gè)字符是沒(méi)有異議的茵烈,但是不同語(yǔ)系的人對(duì)于其他字符的需求是不一樣的百匆,所以對(duì)于剩下的 128 個(gè)字符的擴(kuò)展會(huì)千奇百怪。而且更加混亂的是呜投,在亞洲的語(yǔ)言系統(tǒng)中有更多的字符加匈,一個(gè)字節(jié)無(wú)論如何也滿足不了需求了存璃。例如僅漢字就有 10 萬(wàn)多個(gè),一個(gè)字節(jié)的 256 表示方式怎么能夠滿足呢雕拼。于是就又產(chǎn)生了各種多字節(jié)的表示一個(gè)字符方法(gbk 就是其中一種)纵东,這就使整個(gè)局面更加的混亂不堪。(希望看到這里的你不再認(rèn)為一個(gè)字節(jié)就是一個(gè)字符啥寇,一個(gè)字符就是8比特)偎球。每個(gè)語(yǔ)系都有自己特定的編碼頁(yè)(code pages)的狀況,使得不同的語(yǔ)言出現(xiàn)在同一臺(tái)計(jì)算機(jī)上辑甜,不同語(yǔ)系的人在網(wǎng)絡(luò)上進(jìn)行交流都成了癡人說(shuō)夢(mèng)衰絮。這時(shí) Unicode 出現(xiàn)了。

Unicode

Unicode 就是給計(jì)算機(jī)中所有的字符各自分配一個(gè)代號(hào)栈戳。Unicode 通俗來(lái)說(shuō)是什么呢岂傲?就是現(xiàn)在實(shí)現(xiàn)共產(chǎn)主義了,各國(guó)人民不在需要自己特定的國(guó)家身份證子檀,而是給每人一張全世界通用的身份證镊掖。Unicode 是屬于編碼字符集(CCS)的范圍。Unicode 所做的事情就是將我們需要表示的字符表中的每個(gè)字符映射成一個(gè)數(shù)字褂痰,這個(gè)數(shù)字被稱為相應(yīng)字符的碼點(diǎn)(code point)亩进。例如“嚴(yán)”字在 Unicode 中對(duì)應(yīng)的碼點(diǎn)是 U+0x4E25。

到目前為止缩歪,我們只是找到了一堆字符和數(shù)字之間的映射關(guān)系而已归薛,只到了CCS的層次。這些數(shù)字如何在計(jì)算機(jī)和網(wǎng)絡(luò)中存儲(chǔ)和展示還沒(méi)有提到匪蝙。

字符編碼

前面還都屬于字符集的概念主籍,現(xiàn)在終于到 CEF 的層次了。為了便于計(jì)算的存儲(chǔ)和處理逛球,現(xiàn)在我們要把哪些純數(shù)學(xué)數(shù)字對(duì)應(yīng)成有限長(zhǎng)度的比特值了千元。最直觀的設(shè)計(jì)當(dāng)然是一個(gè)字符的碼點(diǎn)是什么數(shù)字,我們就把這個(gè)數(shù)字轉(zhuǎn)換成相應(yīng)的二進(jìn)制表示颤绕,例如“嚴(yán)”在 Unicode 中對(duì)應(yīng)的數(shù)字是 0x4E25,他的二進(jìn)制是100 1110 0010 0101幸海,也就是嚴(yán)這個(gè)字需要兩個(gè)字節(jié)進(jìn)行存儲(chǔ)。按照這種方法大部分漢字都可以用兩個(gè)字節(jié)來(lái)表示了奥务。但是還有其他語(yǔ)系的存在物独,沒(méi)準(zhǔn)兒他們所使用的字符用這種方法轉(zhuǎn)換就需要 4 個(gè)字節(jié)。這樣問(wèn)題又來(lái)了到底該使用幾個(gè)字節(jié)表示一個(gè)字符呢氯葬?如果規(guī)定兩個(gè)字節(jié)挡篓,有的字符會(huì)表示不出來(lái),如果規(guī)定較多的字節(jié)表示一個(gè)字符帚称,很多人又不答應(yīng)瞻凤,因?yàn)楸緛?lái)有些語(yǔ)言的字符兩個(gè)字節(jié)處理就可以了憨攒,憑什么用更多的字節(jié)表示,多么浪費(fèi)阀参。

這時(shí)就會(huì)想可不可以用變長(zhǎng)的字節(jié)來(lái)存儲(chǔ)一個(gè)字符呢肝集?如果使用了變長(zhǎng)的字節(jié)表示一個(gè)字符,那就必須要知道是幾個(gè)字節(jié)表示了一個(gè)字符蛛壳,要不然計(jì)算機(jī)可沒(méi)那么聰明杏瞻。下面介紹一下最常用的 UTF-8(UTF 是Unicode Transformation Format的縮寫(xiě))的設(shè)計(jì)。請(qǐng)看下圖(來(lái)自阮一峰的博客衙荐,博客地址:https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

其中:x 表示可用的位

image

通過(guò) UTF-8 的對(duì)應(yīng)關(guān)系可以把每個(gè)字符在Unicode 中對(duì)應(yīng)的碼點(diǎn)捞挥,轉(zhuǎn)換成相應(yīng)的計(jì)算機(jī)的二進(jìn)制表示∮且鳎可以發(fā)現(xiàn)按照 UTF-8 進(jìn)行轉(zhuǎn)換是完全兼容原先的 ASCII 的砌函;而且在多字節(jié)表示一個(gè)字符時(shí),開(kāi)頭有幾個(gè) 1 就表示這個(gè)字符按照 UTF-8 轉(zhuǎn)換后由幾個(gè)字節(jié)表示溜族。下面一個(gè)實(shí)例子來(lái)自阮一峰的博客讹俊。

已知“嚴(yán)”的unicode是4E25(100111000100101),根據(jù)上表煌抒,可以發(fā)現(xiàn)4E25處在第三行的范圍內(nèi)(0000 0800-0000 FFFF)仍劈,因此“嚴(yán)”的UTF-8編碼需要三個(gè)字節(jié),即格式是“1110xxxx 10xxxxxx 10xxxxxx”寡壮。然后贩疙,從“嚴(yán)”的最后一個(gè)二進(jìn)制位開(kāi)始,依次從后向前填入格式中的x况既,多出的位補(bǔ)0这溅。這樣就得到了,“嚴(yán)”的UTF-8編碼是“11100100 10111000 10100101”棒仍,轉(zhuǎn)換成十六進(jìn)制就是0xE4B8A5芍躏。

注:【依次從后向前填入格式中的x】意思是,將“嚴(yán)”的二進(jìn)制表示從后往前降狠,依次替代 x

除了 UTF-8 這種轉(zhuǎn)換方法,還存在 UTF-16庇楞,UTF-32 等等轉(zhuǎn)換方法榜配。這里就不再多做介紹。(注意UTF后邊的數(shù)字代表的是碼元的大小吕晌。碼元(Code Unit)是指一個(gè)已編碼的文本中具有最短的比特組合的單元蛋褥。對(duì)于 UTF-8 來(lái)說(shuō),碼元是 8 比特長(zhǎng)睛驳;對(duì)于 UTF-16 來(lái)說(shuō)烙心,碼元是 16 比特長(zhǎng)膜廊。換一種說(shuō)法就是 UTF-8 的是以一個(gè)字節(jié)為最小單位的,UTF-16 是以兩個(gè)字節(jié)為最小單位的淫茵。)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末爪瓜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子匙瘪,更是在濱河造成了極大的恐慌铆铆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丹喻,死亡現(xiàn)場(chǎng)離奇詭異薄货,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碍论,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)谅猾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鳍悠,你說(shuō)我怎么就攤上這事税娜。” “怎么了贼涩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵巧涧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我遥倦,道長(zhǎng)谤绳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任袒哥,我火速辦了婚禮缩筛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堡称。我一直安慰自己瞎抛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布却紧。 她就那樣靜靜地躺著桐臊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晓殊。 梳的紋絲不亂的頭發(fā)上断凶,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音巫俺,去河邊找鬼认烁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的却嗡。 我是一名探鬼主播舶沛,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窗价!你這毒婦竟也來(lái)了如庭?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤舌镶,失蹤者是張志新(化名)和其女友劉穎柱彻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體餐胀,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哟楷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了否灾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卖擅。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖墨技,靈堂內(nèi)的尸體忽然破棺而出惩阶,到底是詐尸還是另有隱情,我是刑警寧澤扣汪,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布断楷,位于F島的核電站,受9級(jí)特大地震影響崭别,放射性物質(zhì)發(fā)生泄漏冬筒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一茅主、第九天 我趴在偏房一處隱蔽的房頂上張望舞痰。 院中可真熱鬧,春花似錦诀姚、人聲如沸响牛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)呀打。三九已至,卻和暖如春糯笙,著一層夾襖步出監(jiān)牢的瞬間贬丛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工炬丸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓稠炬,卻偏偏與公主長(zhǎng)得像焕阿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子首启,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容