前端培训-中级阶段(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. 前端培训目录、前端培训规划、前端培训计划
相关文章
相关标签/搜索