概述
Base64是加密算法吗?它有什么作用?具体算法是怎么样的?为什么叫Base64?
Base64是什么?
Base64是一种二进制到文本的编码方式。如果要更具体一点的话,可以认为它是一种将 byte数组编码为字符串的方法,而且编码出的字符串只包含ASCII基础字符。
值得注意的是Base64不是加密算法,其仅仅是一种编码方式。
为什么叫Base64?
因为它是基于(Base)64个字符的一种编码方式。使用其编码后的文本只包含64个ASCII码字符(偶尔加一个填充字符=),如下所示:
Base64使用到的64个字符:
A-Z 26个
a-z 26个
0-9 10个
+ 1个
/ 1个
下图是Base64码表,可以看到从0到63的每个数字都对应一个上面的一个字符。
Base64解决什么问题?
解决各系统以及传输协议中二进制不兼容的问题而生的。
为什么Base64大家就兼容了呢?
因为Base64满足了各方的需求,各方只保证支持ASIIC中那些基础字符,其他的不能保证,于是Base64就去从那些基础字符里挑了64个,所以大家都高兴了。
目前由于传输导致的二进制改变已经很少见了,各种系统对二进制的兼容性处理也越来越好。假如你告诉我这一串01是一张jpg格式的图片,那我就按照jpg算法将其恢复成一张jpg图片,所以大家都很高兴。
使用场景
- 证书
- 电子邮件的附件,因为附件往往有不可见字符
- xml 中如果像嵌入另外一个 xml 文件,直接嵌入,往往 xml 标签就乱套了, 不容易解析,因此,需要把 xml 编译成字节数组的字符串,编译成可见字符。
- 网页中的一些小图片,可以直接以 base64 编码的方式嵌入,不用再链接请求消耗网络资源。
- 较老的纯文本协议 SMTP ,这些文本偶尔传输一个文件时,需要用 base64
Base64算法
这里只做简单介绍,详情请参考相关技术文档
使用 Base64 进行编码,大致可以分为 4 步:
- 将原始数据每三个字节作为一组,每个字节是8个bit,所以一共是 24 个 bit
- 将 24 个 bit 分为四组,每组 6 个 bit
- 在每组前面加补 00,将其补全成四组8个bit
到此步,原生数据的3个字节已经变成4个字节了,增大了将近30%
- 根据Base64码表得到扩展后每个字节的对应符号(见上图)
下图是维基百科上面的一个例子
假如我们的原文为Man,那么下图演示了如何按照上面的步骤将其编码为Base64字符串
可以发现Man对应的Base64为TWFu.现在大家应该明白为什么只有64个字符了吧?
因为算法将8bit分割成6bit,而6bit的取值范围为0~63。
Base64字符串末尾的=
有时我们会在Base64字符末尾会看到=,有时1个,有时2个,这是为啥?
通过上面的我们知道了Base64编码过程是3个字符一组的进行,如果原文长度不是3的倍数怎么办呢?
例如我们的原文为Ma,它不够3个,那么只能在编码后的字符串中补=了。
缺一个字符补一个,缺两个补两个即可,所以有时候你会看见base64字符串结尾有1个或者2个=。
Base64 DataURI格式
有时你会发现web页面传给你的base64字符串前面有类似下面的内容。
data:image/jpeg;base64, /9j/4AA...
这是DataURI,大部分浏览器支持直接打开这类二进制数据,但是我们要格外注意,如果你只是想要真实的Base64内容就需要取,后边的内容
Java如何对base64进行编码和解码
base64编码
即将文本或者二进制内容转换为base64字符串
例如将aaa这段文本转换为base64的byte数组,如果你想要base64的字符串,直接将其转换为String即可。
其实Java还为我们提供了一个包装方法encodeToString(byte[]),使用其可以直接的到base64字符串
byte[] encodeBytes= Base64.getEncoder().encode("aaa".getBytes(StandardCharsets.UTF_8));
base64解码
解码与编码使用方式一样。
byte[] decodeBytes = Base64.getDecoder().decode("TWE=".getBytes(StandardCharsets.UTF_8));
这次的解码方法就只能获得byte[]了,因为要解码的base64字符串可以是任何内容,文本,图片,视频…
解码,为什么要从一个byte[]转换为另一个byte[]呢?
[
](https://blog.csdn.net/ShuSheng0007/article/details/118220299)