概述
本文經由過程引見Unicode編碼以及對應的兩種編碼體式格局UTF-8和UTF-16,讓讀者能夠相識關於字符串編碼的相干學問,同時能夠弄清楚Unicode和UTF-8和UTF-16之間的關聯。
本文的主要內容為:
- Unicode編碼,包含Unicode編碼基本學問以及與UTF-8和UTF-16這兩種編碼體式格局的關聯
- UTF-8編碼,包含基本觀點和Unicode編碼轉換到UTF-8編碼體式格局
- UTF-16編碼,包含基本觀點和Unicode編碼轉換到UTF-16編碼體式格局
- JavaScript中string與DOMString
本文作為utfx.js源碼剖析的基本學問貯備文章,經由過程相識UTF-8和UTF-16這兩種編碼體式格局,讀者能夠明白運用JavaScript舉行編碼轉換的道理。
假如想相識編碼轉換的運用場景,能夠瀏覽我之前的博客WebSocket系列之JavaScript字符串怎樣與二進制數據間舉行相互轉換。
假如想相識utfx.js相干的源碼內容,能夠關注我的後續文章。
Unicode編碼
觀點
Unicode(
一致碼、萬國碼、單一碼)是計算機科學範疇里的一項業界規範,包含字符集、編碼方案等。Unicode 是為相識決傳統的字符編碼方案的局限而發生的,它為每種言語中的每一個字符設定了一致而且唯一的
二進制編碼,以滿足跨言語、跨平台舉行文本轉換、處置懲罰的請求。1990年最先研發,1994年正式宣布。
一般Unicode編碼是經由過程2 Byte來示意一個字符的,如U+A12B
,2 Byte的二進制示意要領效果就是1010(A)0001(1) 0010(2)1011(B)
。
簡樸引見完了Unicode,我們來看下UTF-8和UTF-16。須要注重的是:UTF是Unicode TransferFormat的縮寫,UTF-8和UTF-16都是把Unicode碼轉換成遞次數據的一種編碼體式格局。
UTF-8
觀點
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,又稱萬國碼。由Ken Thompson於1992年建立。如今已規範化為RFC 3629。UTF-8用1到6個字節編碼Unicode字符。用在網頁上能夠一致頁面顯現中文簡體繁體及別的言語(如英文,日文,韓文)。
經由過程上面的引見我們能夠曉得,UTF-8是一種異常通用的可變長字符編碼體式格局。
起首,我們來引見下什麼叫做可變長編碼?可變長編碼就是指在針對某個字符舉行編碼時,他的示意長度是不牢固的。像UTF-8內里,ASCII所示意的字符集就是用1 Byte來示意,而大部份漢字則是用3 Byte來示意。
相較於Unicode一致運用2 Byte來示意字符,在碰到大部份字符都能夠用1 Byte示意時,能夠節約很多存儲空間。然則,假如碰到須要用凌駕2 Byte來示意的字符,那末UTF-8的編碼體式格局則會斲喪更多的存儲空間。
示意體式格局
經由過程上面的引見我們能夠曉得,差別的Unicode碼在UTF-8中佔用了差別的存儲空間。下面我們就經由過程一個表格來看下將Unicode字符轉換為UTF-8編碼體式格局的詳細步驟。个中的?
示意轉換成UTF-8編碼后,Unicode碼佔用的二進制位置。
Unicode碼局限 | UTF-8編碼體式格局 |
---|---|
U+0000 ~U+007F | 0???????? |
U+0080 ~U+07FF | 110????? 10?????? |
U+0800 ~U+FFFF | 1110???? 10?????? 10?????? |
U+10000 ~U+10FFFF | 11110??? 10?????? 10?????? 10?????? |
當我們獲得Unicode碼后,我們先依據上面的這個表推斷其所處的局限,然後將Unicode碼轉換為二進制示意,從后往前截取UTF-8編碼中所留為之長度,夙昔今後順次填入對應位置,所即可獲得UTF-8的編碼。我們舉兩個例子來看下:
-
U+0020
,這個字符的小於0000 007F,所以只須要用1 Byte來舉行編碼。U+0020
的二進制示意為0000(0)0000(0) 0010(2)0000(0)
,那末從后往前截取7位獲得010 0000
,放入UTF-8編碼體式格局中,獲得的效果為00101111
,轉換為十六進制獲得2F
。因而存儲在內存中的的遞次就是2F
。 -
U+A12B
,這個字符大於0000 0800,小於0000 FFFF,因而須要用3 Byte來舉行編碼。U+A12B
的二進制示意為1010(A)0001(1) 0010(2)1011(B)
。,那末從后往前截取16位獲得10100001 00101011
(Unicode碼自身),放入UTF-8編碼中,獲得的效果為11101010 10000100 10101011
,轉換十六進制獲得EA84AB
。因而,存儲在內存中的遞次就是EA 84 AB
。
經由過程上面的例子,我置信人人對UTF-8的編碼有了一個深切的明白。下面,讓我們來看下另一種編碼體式格局——UTF-16。
UTF-16
觀點
UTF-16是
Unicode字符編碼五條理模子的第三層:字符編碼錶(Character Encoding Form,也稱為 “storage format”)的一種完成體式格局。即把Unicode字符集的籠統碼位映照為16位長的整數(即碼元, 長度為2 Byte)的序列,用於數據存儲或通報。Unicode字符的碼位,須要1個或許2個16位長的碼元來示意,因而這是一個變長示意。
援用維基百科中關於UTF-16編碼的詮釋我們能夠曉得,UTF-16起碼也會用2 Byte來示意一個字符,因而沒有辦法兼容ASCII編碼(ASCII編碼運用1 Byte來舉行存儲)。
示意體式格局
在UTF-16中,我們將Unicode分為了兩個局限,離別經由過程差別的體式格局舉行存儲。詳細示意見下圖。
Unicode局限 | UTF-16編碼體式格局 |
---|---|
U+000 ~U+FFFF | 2 Byte存儲,編碼后即是Unicode值 |
U+10000 ~U+10FFFF | 4 Byte存儲,現將Unicode值減去(0x10000),獲得20bit長的值。再將Unicode分為高10位和低10位。UTF-16編碼的高位是2 Byte,高10位Unicode局限為0 –0x3FF ,將Unicode值加上0XD800 ,獲得高位代辦(或稱為前導代辦,存儲高位);低位也是2 Byte,低十位Unicode局限一樣為0 ~0x3FF ,將Unicode值加上0xDC00 ,獲得低位代辦(或稱為後尾代辦,存儲低位) |
依據上面的轉換體式格局,我們就能夠將Unicode碼依據UTF-16的編碼體式格局舉行轉換。下面我們依然經由過程兩個例子來看下:
-
U+0020
,這個值的局限在第一部份,即經由UTF-16編碼后,效果依然為U+0020
,在內存中的遞次為00 20
。 -
U+12345
, 這個值的局限在第二部份,因而須要先減去0x10000
,獲得0x02345
,拆分紅高10位00 0000 1000
和低10位11 0100 0101
。依據上面劃定規矩加上特定值后,高位代辦值為D808
,低位代辦值為DF45
,終究內存中的遞次為D8 08 DF 45
。
JavaScript中的string與DOMString
在JavaScript中,一切的string範例(或許被稱為DOMString)都是運用UTF-16編碼的。
因而,當我們須要轉換成二進制與後端舉行通訊時,須要注重相干的編碼體式格局。
總結
本文經由過程對Unicode編碼和UTF-8和UTF-16兩種編碼體式格局舉行引見,讓人人相識Unicode編碼以及相干的兩種遞次數據編碼體式格局。
本文是作為utfx.js源碼剖析的基本學問貯備文章,在稍後的時候將會給人人帶來相干內容的後續文章——utfx.js源碼剖析,讓人人能夠相識在JavaScript中怎樣舉行相干的編碼轉換。