在地铁上,漫漫路途,闲来无事涉猎一些文章,偶然读到的一篇关于base64的文章,正好自己最近在接触这相关方面,于是搜索了一番,也是收获不少,特此记录分享。
任何事物的出现,总是有它的独到之处无可替代的,那么base64是干什么用的,有什么需求,好处,以及其具体的实现是如何的呢?
base64 最早就是用来邮件传输协议中的,原因是邮件传输协议只支持 ascii 字符传递,因此如果要传输二进制文件,如:图片、视频是无法实现的。因此 base64 就可以用来将二进制文件内容编码为只包含 ascii 字符的内容,这样就可以传输了;
以前的交换机只能处理标准ascii码。也就是说最高位是0。那么base64就是一种编码方法。保证一般数据最高位为0。怎么做?现在假设我们有3字节24位数据流。我们现在每6位切一刀。在这6位前面补00 这样三字节变成四字节。而且保证最高位为0 这样就能在网络上传输了。
ascii码的128~255之间的值是不可见字符。而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。
那么Base64到底是怎样编码的呢?简单来说,任何一个数据无非可以看作一个比特流,如01000100010011101100111010111100011001010……那么我们取6个比特为一组,计算它的ascii值,得到一个字符,这个字符肯定是可见字符,好,把它对应的字符写出来,再取6个比特,计算…,如此下去,直到最后,就完成了编码。
1.标准
base64只有64个字符(英文大小写、数字和+、/)以及用作后缀等号;
2.base64是把3个字节变成4个可打印字符,所以base64编码后的字符串一定能被4整除(不算用作后缀的等号);
3.等号一定用作后缀,且数目一定是0个、1个或2个。这是因为如果原文长度不能被3整除,base64要在后面添加\0凑齐3n位。为了正确还原,添加了几个\0就加上几个等号。显然添加等号的数目只能是0、1或2;
4.严格来说base64不能算是一种加密,只能说是编码转换。使用base64的初衷。是为了方便把含有不可见字符串的信息用可见字符串表示出来,以便复制粘贴;
提供一个工作中用到过的base64场景
一个xml当中包含另一个xml数据,此时如果将xml数据直接写入显然不合适,将xml进行适当编码存入较为方便,事实上xml当中的字符一般都是可见字符(0-127之间),但是由于中文的存在,可能存在不可见字符,直接将字符打印在外层xml的数据中显然不合理,那么怎么办呢?可以使用base64进行编码,然后存入xml,解码反之其实还有个办法,将byte的值写在xml当中,空格或者,分开,这样也可以将byte数据传入,不过这样更浪费空间,并且不易保存.
另一个,比如http协议当中的key value字段,必须进行URLEncode 不然出现的等号可能使解析失败 空格也会使http请求解析出现问题,比如 请求行就是以空格来划分的 POST /guowuxin/hehe HTTP/1.1 又比如有些文本协议不支持不可见字符的传递,只能用大于32的可见字符来传递信息(协议规定);
下面是一个简单的base64编码实例。
在这里,三个字符组成的输入值“Ow!”是base64编码的,得到的是4个字符的base64编码值“T3ch”。它是按以下方式工作的。
(1) 字符串"Ow!"被拆分成3个8位的字节(0x4F、0x77、0x21)。
(2) 这3个字节构成了一个24为的二进制01001111 01110111 00100001。
(3) 这些为被划分为一些6位的序列010011、110111、011100、1000001.
(4) 每个6位值都表示了从0~63之间的数字,对应base64字母表中的64个字符之一。得到的base64编码字符串是4个字符的字符串“T3ch”。然后就可以通过线路将这个字符串作为“安全的”8位字符传送出去,因为只用了一些移植性最好的字符(字母、数字等)。
// 现在将字符串"Ow!"转换为base64编码值
var str = 'Ow!';
// 或去字符串的二进制码
var binary = [];
for (var i = 0; i < str.length; i++) {
// 转换为二进制表示
var binStr = str.charCodeAt(i).toString(2);
// 将得到的二进制放入数组中得到
// ['1001111','1110111','100001']
// 因为一个正常的二进制字节都是由8bit组成的,不够8bit的话不表示.上面得到的都不够8bit所以前面我们手动给补
0,就得到了
// ['01001111','01110111','00100001']
binary.push(binStr);
}
// 1 把字符串按照6位分开,进行分割,得到['010011','110111','011100','1000001']
// 2 将每一个转换为十进制分别对于[19,55,28,33];
// 3 将每一位数字分别对于上面提供的base64对应表,得到对应的编码,分别对于 T 3 c h
// 4 最后就会得到base64编码T3ch
console.log('字符"Ow!"最后得到的base64编码为"T3ch"');
主要内容学习于网络,部分内容来源:https://www.zhihu.com/question/36306744/answer/71626823