前端最基礎的就是 HTML+CSS+Javascript
。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS
),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。html
編碼解碼對於web開發來講,有可能最多見的是URL編碼(encode
decode
)。前端
計算機處理的內容是二進制,對應開和關的狀態。若是要處理文本,也是把文本轉換爲數字而後作比對。最先的計算機在設計時採用8個比特(bit)做爲一個字節(byte)。
一個字節能表示的最大的整數就是255(0b11111111==255
)。這255個數字被用來表示大小寫英文字母、數字和一些符號,這個編碼表被稱爲ASCII編碼,好比大寫字母A的編碼是65,小寫字母a的編碼是97。web
ASCII 對照表segmentfault
若是要表示中文,顯然ASCII的一個字節是不夠的,至少須要兩個字節,並且還不能和ASCII編碼衝突。
因此,中國製定了GB2312編碼(國標2312編碼),用來把中文編進去。瀏覽器
Unicode(萬國碼),包括字符集、編碼方案等。
Unicode 是爲了解決傳統的字符編碼方案的侷限而產生的,它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言、跨平臺進行文本轉換、處理的要求。1990年開始研發,1994年正式公佈。
Unicode一般用兩個字節表示一個字符,原有的英文編碼從單字節變成雙字節,只須要把高字節所有填爲0就能夠。目前的Unicode字符集爲0x0000
至0x10FFFF
,分爲17組編排,,每平面擁有65536個碼位,共1114112個碼位。服務器
Unicode 到目前爲止所定義的十七個平面中,第0平面(BMP)最爲重要。微信
中文範圍 4E00-9FA5
:CJK 統一表意符號 (CJK Unified Ideographs)性能
在Unicode中:「李」字對應的數字是26446
(十進制),十六進制表示爲0x674e
。編碼
Unicode 只是一個大的合集,UTF-8、UTF-16、UTF-32纔是將數字轉換到程序數據的編碼方案。
UTF是Unicode Transformation Format的縮寫,能夠翻譯成Unicode字符集轉換格式,即怎樣將Unicode定義的數字轉換成程序數據。url
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編碼以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編碼以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編碼是一種瀏覽器用來打包表單輸入的格式。
瀏覽器將表單中獲取到的內容,以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 "