共计 3152 个字符,预计需要花费 8 分钟才能阅读完成。
前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。
编码解码对于 web 开发来说,有可能最常见的是URL 编码(encode
decode
)。
ASCII 编码
计算机处理的内容是二进制 ,对应开和关的状态。如果要处理文本,也是把文本转换为数字然后做比对。最早的计算机在设计时采用 8 个比特(bit)作为一个字节(byte)。
一个字节能表示的最大的整数就是 255(0b11111111==255
)。这 255 个数字被用来表示大小写英文字母、数字和一些符号,这个 编码表被称为 ASCII 编码,比如大写字母 A 的编码是 65,小写字母 a 的编码是 97。
ASCII 对照表
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 "
微信公众号:前端 linong
参考文献
- 前端培训目录、前端培训规划、前端培训计划