WEB开发常用编码 Base64、BCD码、URL编码、Unicode、utf-8 的简单总结

Unicode 创造史参考 https://www.jianshu.com/p/36d20de2a1ee

Base64

Base64 是网络上最常见的用于传输 8bit 字节代码的编码方式之一。

  • 有时候我们需要把二进制数据编码,然后放在URL中传输,以便不会被人直接看出。
  • 通过编码防止意外生成的系统定界字符
  • 编码为base64之前 数据是以字节数组存放, 里面任何二进制字符都是可能的。如果有的语言以\0作为字符串结束标志,正好字节数组里面有\0的话,可能会有问题。

简单来讲,Base64就是用下列总计64个字符去表示二进制数据的:

  • A-Z
  • a-z
  • 0-9
  • +
  • /

编码规则:

  1. 把三个字符变成四个字符
  2. 没76个字符加一个换行符
  3. 最后的结束符也要处理

Base64字符串的长度必然是4的整数倍。由于二进制的字节数不一定是3的整数倍,所以Base64字符串在结尾是可能有空的。这些空的状态,Base64引入第65个字符 “=” 去表示:

对于base64编码,常常在网络中用于编码长标识符。编码规则是每3个8位字节为一组,分成4组6位字节,并且每个字节的高位补零,形成4个8位的字节。base64编码具有可逆性。

w3c浏览器内置了window.btoa()window.atob() 来完成二进制数据或者ASCII字符到base64的转换(注意:该方法只能用于ASCII码成Base64,不适用中文等)

  • atob则是ascii to binary,用于将ascii码解析成binary数据,即Base64的解码过程
  • btoa是binary to ascii,用于将binary的数据用ascii码表示,即Base64的编码过程

"ABC" 按照 Base64编码"QUJD"
"中国" 按照 Base64编码"JXU0RTJEJXU1NkZE"

8421 BCD

bcd码用来打印二进制。把任意一个字符变成2个可见的十六进制字符(0-9a-z 或 0-9A-z)。
相比于Base64的隐蔽性,BCD码的优势在于其可读性好。

URL

对于uri的编解码,在js中有3对函数,分别是escape/unescape, encodeURI/decodeURI, encodeURIComponent/decodeURIComponent

它们的适用范围不同,而且遵循的编码规范也不同。

相同点:
对于上述函数而言,所有的ASCII的字符编码相同,采用%XX的形式。

不同点:

  • 而对于unicode字符,escape编码形式为%uXXXX
  • 而其余两个函数则先将unicode字符按照utf-8对其进行编码,然后继续进行uri编码(百分号)。对于中文字符,每个字符用urf-8编码则为3个字节,然后在每个字节前面加上%即可。

三个函数对应的安全字符

  • escape(69个):*/@±._0-9a-zA-Z
  • encodeURI(82个):!#$&’()*+,/:;=?@-._~0-9a-zA-Z
  • encodeURIComponent(71个):!’()*-._~0-9a-zA-Z
encodeURIComponent(s) = escape(unicodeToUTF8(s));
unicodeToUTF8(s) = unescape(encodeURIComponent(s));

ASCII

在计算机发明的时候 ,由于计算机你只能表示二进制的数据,美帝人民为了交流通信方便,约定了一个编码系统,就是ASCII码,把abc…xyz…ABC…XYZ…!@#…等字符分别和0,1,2,3,4…对应,发现差不多刚好128个数,半个字节的长度,为了防止以后需要为新的符号编码,于是干脆取一个字节,最高位置为0。后七位从0-127分别对每一个符号编码。

ISO

后来欧洲人也玩计算机,发现不行啊,还有很多符号(法语,德语)ASCII没办法表示啊,于是欧洲人自己也撸了一套编码,一个字节的长度,把最高位也用掉了。这套编码叫ISO。

GBK

中国人不高兴了,特么我们汉字有几万个,常用的就有几千个,没有两个字节根本交不了货。于是勤劳勇敢的中国人民就破天荒的用了两个字节来表示中文。整出一套GBK。为了现实我中华民族兼容并蓄,我们兼容了ASCII编码。

gbk编码规定,计算机不能在每次都只读一个字节那么死板了,你要先看看第一位是不是为0,要是为0 的话,就当作ASCII码来读入一个字节,不然的话就读入两个字节。

Unicode

Unicode 是容纳世界所有文字符号的国际标准编码,使用四个字节为每个字符编码。

function toUnicode(data) {
	if(data == '' || typeof data == 'undefined') return '';
	let str = '';
	for(let i=0; i < data.length; i++) {
		let tmp = data.charCodeAt(i).toString(16);
		//由于Unicode固定使用四个字节为每个字符编码,因此如果没达到就要补全
		while(tmp.length < 4) {
			tmp = "0" + tmp;
		}
		str += "\\u" + tmp;
	};
	return str;
}
function formUnicode(data) {
	if(data == '' || typeof data == 'undefined') return '';
	return unescape(data.replace(/\\u/g, "%u"));
	//return eval("'" + data + "'").toString();
}

"ABC" 按照 Unicode编码"\u0041\u0042\u0043"
"中国" 按照 Unicode编码"\u4e2d\u56fd"

UTF-8

但是如果类似于1号编码这样的小数据编号也要三个字节的话,那么也就是0x000001,这简直就是浪费啊,明明一个字节就可以表示了,你非得整三个。于是就出现了uft-8,utf-16,utf-32这些编码方案。

utf-8为了节省资源,采用变长编码,编码长度从1个字节到6个字节不等

在这里插入图片描述

  • 如果开头是0,表示只有1个字节;
  • 否则,头一个字节的第一个0前面多少个1就表示有多少个字节
    • 第二个字节起,每个字节都用 10 打头
    • 第二个字节比第一个多了 4 比特(共11比特),其后每多一个字节,增加 5 比特
    • 从第二位开始,除了标志位,还有一部分数值未利用(少一个字节可以表示的最大值)

utf-8最小是1字节,utf-16最小是2字节,utf-32最小是4字节。所以英文在utf-16中也是2个字节,而在utf-8中则是1个字节。在当大部分是英文的时候utf-8更加节省资源。如果在我们在中文世界里来比较他们,则是utf-16更加节省资源。

"ABC" 按照 urf-8编码"0x410x420x43"
"中国" 按照 urf-8编码"0xE40xB80xAD0xE50x9B0xBD"

function toUtf8(data) {
	if(data == '' || typeof data == 'undefined') return '';
	let str = '';
	data = unescape(encodeURIComponent(data));
	for(let i=0; i < data.length; i++) {
		let tmp = data.charCodeAt(i).toString(16).toUpperCase();
		while(tmp.length < 2) {
			tmp = "0" + tmp;
		}
		str += "0x" + tmp;
	};
	return str;
}
function fromUtf8(data) {
	if(data == '' || typeof data == 'undefined') return '';
	let str = '';
	data.replace(/0x(\w{2})/g, function(){
		str += String.fromCharCode(parseInt(arguments[1], 16));
	});
	return decodeURIComponent(escape(str));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值