前端培訓-中級階段(16)- Unicode和UTF編碼(2019-09-12期)

前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。html

編碼解碼對於web開發來講,有可能最多見的是URL編碼(encode decode)。前端

ASCII 編碼

計算機處理的內容是二進制,對應開和關的狀態。若是要處理文本,也是把文本轉換爲數字而後作比對。最先的計算機在設計時採用8個比特(bit)做爲一個字節(byte)
一個字節能表示的最大的整數就是2550b11111111==255)。這255個數字被用來表示大小寫英文字母、數字和一些符號,這個編碼表被稱爲ASCII編碼,好比大寫字母A的編碼是65,小寫字母a的編碼是97。web

ASCII 對照表segmentfault

GB2312編碼

若是要表示中文,顯然ASCII的一個字節是不夠的,至少須要兩個字節,並且還不能和ASCII編碼衝突。
因此,中國製定了GB2312編碼(國標2312編碼),用來把中文編進去。瀏覽器

Unicode 編碼

Unicode(萬國碼),包括字符集、編碼方案等。
Unicode 是爲了解決傳統的字符編碼方案的侷限而產生的,它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言跨平臺進行文本轉換、處理的要求。1990年開始研發,1994年正式公佈。
Unicode一般用兩個字節表示一個字符原有的英文編碼從單字節變成雙字節,只須要把高字節所有填爲0就能夠。目前的Unicode字符集爲0x00000x10FFFF,分爲17組編排,,每平面擁有65536個碼位,共1114112個碼位服務器

Unicode 到目前爲止所定義的十七個平面中,第0平面(BMP)最爲重要。微信

中文範圍 4E00-9FA5:CJK 統一表意符號 (CJK Unified Ideographs)性能

Unicode中:「李」字對應的數字是26446(十進制),十六進制表示爲0x674e編碼

UTF 編碼系列

Unicode 只是一個大的合集,UTF-8UTF-16UTF-32纔是將數字轉換到程序數據的編碼方案。
UTFUnicode Transformation Format的縮寫,能夠翻譯成Unicode字符集轉換格式,即怎樣將Unicode定義的數字轉換成程序數據。url

UTF-8

UTF-8的特色是對不一樣範圍的字符使用不一樣長度的編碼,這點極大的縮小了文件的大小。固然,也會形成必定的性能浪費,

對於0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼徹底相同。
對於超過區間的字符,最高位非0,10標識當前屬於前面字節的描述字節。110標明這是兩個字節的,後面還會跟着一個字節。

UTF-8編碼的最大長度是4個字節。從表格中能夠看到,4字節模板有21個x,便可以容納21位二進制數字。Unicode的最大碼位0x10FFFF也只有21位。

Unicode編碼(十六進制) UTF-8 字節流(二進制)
000000-00007F 0xxxxxxx
000080-0007FF 110xxxxx 10xxxxxx
000800-00FFFF 1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
「李」 \u674e 11100110 10011101 10001110
「A」 \u0041 01000001

UTF-16

UTF-16編碼以16位無符號整數爲單位。咱們把Unicode編碼記做U。
若是U<0x10000,UTF-16編碼(二進制)就是對應的16位無符號整數。
若是U≥0x10000,先計算U'=U-0x10000,而後將U'寫成二進制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16編碼(二進制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx

這裏,你會好奇,由於第二條規則會和第一條規則重複。爲了將編碼區分開來,Unicode編碼的設計者將0xD800-0xDFFF保留下來,並稱爲代理區(Surrogate)

// D800-DB7F    High Surrogates    高位替代
// 指UTF-16編碼中。兩個位置中的第一個位置
(0xD800).toString(2) == 1101100000000000
(0xDB7F).toString(2) == 1101101101111111

// DC00-DFFF    Low Surrogates     低位替代
// 指UTF-16編碼中。兩個位置中的第二個位置
(0xDC00).toString(2) == "1101110000000000"
(0xDFFF).toString(2) == "1101111111111111"

// DB80-DBFF    High Private Use Surrogates      高位專用替代
(0xDB80).toString(2) == "1101101110000000"
(0xDBFF).toString(2) == "1101101111111111"

UTF-32

UTF-32編碼以32位無符號整數爲單位。Unicode的UTF-32編碼就是其對應的32位無符號整數。

字節序

字節序有兩種,分別是「大端」(Big Endian, BE)和「小端」(Little Endian, LE)。
根據字節序的不一樣,UTF-16可被實現爲UTF-16LE或UTF-16BE,UTF-32可被實現爲UTF-32LE或UTF-32BE。

Unicode編碼 UTF-16LE UTF-16BE UTF32-LE UTF32-BE
0x006C49 49 6C 6C 49 49 6C 00 00 00 00 6C 49
0x020C30 43 D8 30 DC D8 43 DC 30 30 0C 02 00 00 02 0C 30

Unicode標準建議用BOM(Byte Order Mark)來區分字節序,即在傳輸字節流前,先傳輸被做爲BOM的字符「零寬無中斷空格」。這個字符的編碼是FEFF,而反過來的FFFE(UTF-16)和FFFE0000(UTF-32)在Unicode中都是未定義的碼位,不該該出如今實際傳輸中。

UTF編碼 Byte Order Mark (BOM)
UTF-8 without BOM
UTF-8 with BOM EF BB BF
UTF-16LE FF FE
UTF-16BE FE FF
UTF-32LE FF FE 00 00
UTF-32BE 00 00 FE FF

URL編碼/解碼

url編碼是一種瀏覽器用來打包表單輸入的格式
瀏覽器將表單中獲取到的內容,以name=value參數編碼,做爲URL的一部分或者放入body發給服務器。轉換成如:a=1&b=2

基於上面的規則,=或者&都會形成解析異常。因此特殊的字符(不是簡單的七位ASCII,如漢字,關鍵詞),會以%XX這個格式轉義,好比:

字符 encode編碼 utf-8編碼
= %3D 00111101
%E6%9D%8E 11100110 10011101 10001110
// 轉換代碼
encodeURIComponent('李').replace(/%([0-9a-f]{2})/gi, (v,group1)=>parseInt(group1,16).toString(2)+' ') // "11100110 10011101 10001110 "
encodeURIComponent('=').replace(/%([0-9a-f]{2})/gi, (v,group1)=>parseInt(group1,16).toString(2).padStart(8,'0')+' ') //"00111101 "

微信公衆號:前端linong

clipboard.png

參考文獻

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
相關文章
相關標籤/搜索