Base64编码原理

Base64编码原理

前言

​ 最近做一个小需求—用户头像修改,需要传输图片信息,本来我这边定义的接口是```POST Content-Type:Multipart/form-data``,这种结构可以解决带文件的请求,但是前端小哥哥说因为基础组件受限,这种处理起来比较麻烦,沟通了一下最后决定将图片进行Base64编码为字符传输到后端服务,服务端再处理(其实我内心是拒绝的),这就引出了今天的主题-Base64.

介绍

Base64是什么

​ Base64是一种编码格式(有得同学说Base64加密其实是不对的),什么是编码格式?编码格式就是一套字母对照表,各方约定一种对应关系。其采用64个可见字符来表示各种字符而得名,使得即使是特殊字符也不会受限制的传输。

​ Base64 最早就是用来邮件传输协议中的,原因是邮件传输协议只支持 ascii 字符传递,因此如果要传输二进制文件,如:图片、视频是无法实现的。因此 Base64 就可以用来将二进制文件内容编码为只包含 ascii 字符的内容。

​ 我们知道在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。

###Base64应用场景

X.509公钥证书

对证书来说,特别是根证书,一般都是作Base64编码的,因为它要在网上被许多人下载。电子邮件的附件一般也作Base64编码的,因为一个附件数据往往是有不可见字符的。

文本传输

​ 一个xml当中包含另一个xml数据,此时如果将xml数据直接写入显然不合适,将xml进行适当编码存入较为方便,事实上xml当中的字符一般都是可见字符(0-127之间),但是由于中文的存在,可能存在不可见字符,直接将字符打印在外层xml的数据中显然不合理,那么怎么办呢?可以使用base64进行编码,然后存入xml,解码反之其实还有个办法,将byte的值写在xml当中,空格或者,分开,这样也可以将byte数据传入,不过这样更浪费空间,并且不易保存.另一个,

HTTP协议

​ http协议当中的key value字段,必须进行URLEncode 不然出现的等号可能使解析失败 空格也会使http请求解析出现问题,比如 请求行就是以空格来划分的 POST /guowuxin/hehe HTTP/1.1

电子邮件(SMTP协议)

有些文本协议不支持不可见字符的传递,只能用大于32的可见字符来传递信息(协议规定)

图片base64编码

​ 前端在实现页面时,对于一些简单图片,通常会选择将图片内容直接内嵌在页面中,避免不必要的外部资源加载,增大页面加载时间,但是图片数据是二进制数据,该怎么嵌入呢?绝大多数现代浏览器都支持一种名为 Data URLs 的特性,允许使用Base64对图片或其他文件的二进制数据进行编码,将其作为文本字符串嵌入网页中。

原理介绍

编码规则

​ Base64编码之所以称为Base64,是因为其使用64个可见字符来对任意二进制数据进行编码,所以Base64编码本质上是一种将二进制数据转成文本数据的方案。又根据使用场景的不同分为标准Base64和Base64URL(=/在url中为特殊字符,所以替换为其他字符).

下图是对应的编码字符:

Base64编码原理

Base64编码一般经过这几个步骤:

  • 数据转换为二进制
  • 每连续6比特计算其十进制值(每3个原始字符编码成4个字符,如果原始字符串长度不能被3整除,那怎么办?使用0值来补充原始字符串)
  • 查表找出其上一步骤中十进制对应的字符,组成字符串

假设我们要对 Hello! 进行Base64编码,按照ASCII表,其转换过程如下图所示:

Base64编码原理

可知 Hello! 的Base64编码结果为 SGVsbG8h ,原始字符串长度为6个字符,编码后长度为8个字符,每3个原始字符经Base64编码成4个字符,编码前后长度比4/3,这个长度比很重要 - 比原始字符串长度短,则需要使用更大的编码字符集,这并不我们想要的;长度比越大,则需要传输越多的字符,传输时间越长。Base64应用广泛的原因是在字符集大小与长度比之间取得一个较好的平衡,适用于各种场景。

标准Base64编码通常用 = 字符来替换最后的 A,即编码结果为 SGVsbG8hIQ==。因为 = 字符并不在Base64编码索引表中,其意义在于结束符号,在Base64解码时遇到 = 时即可知道一个Base64编码字符串结束。

如果Base64编码字符串不会相互拼接再传输,那么最后的 = 也可以省略,解码时如果发现Base64编码字符串长度不能被4整除,则先补充 = 字符,再解码即可。

解码是对编码的逆向操作,但注意一点:对于最后的两个 = 字符,转换成两个 A 字符,再转成对应的两个6比特二进制0值,接着转成原始字符之前,需要将最后的两个6比特二进制0值丢弃,因为它们实际上不携带有效信息

Base64的优缺点

  • 优点

适用于任何可传输内容的编码

  • 缺点

三个字符编码后变为4个字符,内容大小变大,不适用于大数据量的传输

总结

​ 处处留心皆学问,小小的需求牵出了Base64的编码原理和应用场景。