前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。
编码解码对于web开发来说,有可能最常见的是URL编码(encode
decode
)。
ASCII 编码
计算机处理的内容是二进制,对应开和关的状态。如果要处理文本,也是把文本转换为数字然后做比对。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte)。
一个字节能表示的最大的整数就是255(0b11111111==255
)。这255个数字被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母a的编码是97。
GB2312编码
如果要表示中文,显然ASCII的一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突。
所以,中国制定了GB2312编码(国标2312编码),用来把中文编进去。
Unicode 编码
Unicode(万国码),包括字符集、编码方案等。
Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
Unicode通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0就可以。目前的Unicode字符集为0x0000
至0x10FFFF
,分为17组编排,,每平面拥有65536个码位,共1114112个码位。
Unicode 到目前为止所定义的十七个平面中,第0平面(BMP)最为重要。
中文范围 4E00-9FA5
:CJK 统一表意符号 (CJK Unified Ideographs)
在Unicode中:“李”字对应的数字是26446
(十进制),十六进制表示为0x674e
。
UTF 编码系列
Unicode 只是一个大的合集,UTF-8、UTF-16、UTF-32才是将数字转换到程序数据的编码方案。
UTF是Unicode Transformation Format的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。
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 "
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。