目录
1. 基本原理
Base64
是一种将二进制流表示为 64 个字符的编码方式。标准的 Base64 使用的索引表为:
举个例子,字符串"Base64 编码"
经过编码后的结果为:QmFzZTY0IOe8lueggQ==
。当然,这里隐含了以UTF-8
作为字符编码的前提,如果使用了其他的字符编码方式,用Base64
编码后就不是这个结果了。很多在线编解码的网站其实也是默认使用了UTF-8
,但是没有明确说明。
1.1 标准 Base64 编码步骤
下面解释一下Base64
的编码步骤:
- 步骤1:数据输入在这一步骤,需要将原数据(字符串、图片、音频等任何数据)转换为二进制流。例如前面举的字符串的例子,则需要经过字符编码转换为二进制流。
- 步骤2:分组转换
- 从二进制流头部开始,每 6 位为一组,若不足 6 位,则低位补0
- 每 6 位组成一个新的字节,高位 2 位补 0 ,此时已经获得二进制的
Base64
编码
- 步骤3:转换为字符串将二进制的
Base64
编码每个字节映射为一个字符,例如0000 0000
映射为A
,0011 1111
映射为/
,此时已经获得Base64
编码字符串 - 步骤4:末尾补位标准
Base64
编码字符串的长度为 4 的倍数,否则,在末尾补充=
。例如前面的QmFzZTY0IOe8lueggQ==
长度就是补充了两个=
后,长度为 20。
整个编码步骤并不复杂,我们用一张示意图表示为:
1.2 非标准 Base64
- Url Base 64标准
Base 64
中使用了'/'
,这在URL
和文件系统中存在冲突,因此延伸出 Url Base64 算法,主要就是将'+'
和'/'
符号替换成了'-'
和'_'
符号。 - MIME Base 64这是一种
MIME
友好格式,它输出每行为 76 个字符,每行末需追加回车换行符\r\n
,不论每行是否够 76 个字符,都要添加一个回车换行符
1.3 意义
Base64
能够将任何数据转换为易移植的字符串,避免了传输过程中失真问题。最初,Base64
是为了解决电子邮件中无法直接使用非ASCII
字符的问题。一段数据先经过Base64
编码为ASCII
字符串后,可以在接收端,通过Base64
解码还原为原数据后,而无需担心传输过程中失真。
很多时候,我们都将Base64
编码作为数据加密后的传输 / 存储格式。例如,一段明文数据通过MD5 、SHA
等手段加密后,经过Base64
编码为字符串,就可以很方便地进行传输 & 存储。再比如,网络上的数字证书其实也是使用Base64
编码的形式传输的,我们可以在浏览器上查看百度官网的数字证书:
- 1、 查看百度官网的数字证书
- 2、将证书保存到本地
- 3、证书以 Base64 编码格式存储
需要注意的是,Base64
并不是一种加密方式,明文使用Base64
编码后的字符串通过索引表可以直接还原为明文。因此,Base64
只能作为一种数据的存储格式。
2. 算法实现
2.1 Java 环境
在Java 8
之前,JDK中并没有提供Base64
的算法实现,这其实挺让人纳闷的。虽然源码中sun.misc.BASE64Encoder
,但是它其实并不是公有 API,而是 sun 团队内部使用的 API,最好不要在生产中使用。从Java 8
,JDK 总算是补充了Base64
的实现,例如:
import java.util.Base64; 标准 Base 64 System.out.println(Base64.getEncoder().encodeToString("".getBytes())); Url Base 64 System.out.println(Base64.getUrlEncoder().encodeToString("".getBytes())); MIME Base 64 System.out.println(Base64.getMimeEncoder().encodeToString("".getBytes())); 复制代码
在Java 8
之前,Bouncy Castle
和Apache
也提供了Base64
的算法实现。
2.2 Android环境
Android SDK
提供了Base64
的算法实现,例如:
import android.util.Base64; System.out.println(Base64.encodeToString("".getBytes(),Base64.DEFAULT)); 复制代码
相对于Java 8
的算法实现,Android
提供的 API 更为灵活,可以通过flag
自定义控制算法的输出。
3. 总结
Base 64
能够将任何数据转换为易移植的字符串,避免了传输过程中失真问题。- 需要注意的是,
Base 64
不是一种加密方式,只是一种编码方式。很多时候,我们都将Base64
编码作为数据加密后的传输 / 存储格式