[版权申明] 非商业目的注明出处可自由转载
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/118220299
出自:shusheng007
Base64在日常开发中的出镜率还是比较高的,那你真的了解它吗?它是加密算法吗?它有什么作用?具体算法是怎么样的?为什么叫Base64?如果你不能完全回答上面的问题,可以接着往下看了
Base64是一种二进制到文本的编码方式。如果要更具体一点的话,可以认为它是一种将 byte
数组编码为字符串的方法,而且编码出的字符串只包含ASCII基础字符。
例如字符串ShuSheng007
对应的Base64为U2h1U2hlbmcwMDc=
。其中那个=
比较特殊,是填充符,一会再说。
值得注意的是Base64不是加密算法,其仅仅是一种编码方式,算法也是公开的,所以不能依赖它进行加密。
因为它是基于(Base)64个字符的一种编码方式。使用其编码后的文本只包含64个ASCII码字符(偶尔加一个填充字符=
),如下所示:
Base64使用到的64个字符:
A-Z
26个a-z
26个0-9
10个+
1个/
1个下图是Base64码表,可以看到从0到63的每个数字都对应一个上面的一个字符。
这块还是比较难说清楚的,我们就抓住主要矛盾吧。
假设王二狗给牛翠花通过邮件发情书:
亲爱的翠花我爱你,就像老鼠爱大米…
你是我的心,你是我的肝,你是我生命中的四分之三…
我们首先要明白,网络中信息的传输只能传输0和1
,所以我们首先要将这封情书转成01
序列,那怎么转呢?
这就又涉及到了编码方式,这块展开说能说两天,这里就假设使用UTF-8
转成的byte[]
, 值是我瞎写的
[100][11][1][13]....
这个byte[]
里面的那些数字,传输时候是以二进制形式进行的,格式如下:
011001000001100100000001001101...
那么当牛翠花收到这串数字后再将其按照UTF-8
解码,就能看到二狗的情书了。
如果一切都这么顺利就没base64什么事了。由于信息从王二狗的电脑到牛翠花的电脑中间会经过好多路由器转发,牛翠花电脑上安装的邮件客户端也搞幺蛾子。其中一个叫阿路的路由器发现现在使用的是文本传输协议,而且有个byte的值是[13],而13在ASIIC码中对应回车键,阿路一想,这玩意也表达不出个啥意思,算了给他娘的省略了吧,为下面的兄弟省点宽带,阿路有看到一个byte值为[07]的又自作聪明,因为其在ASIIC中表示铃声,又给省略了。这样等到01序列到达牛翠花的电脑时其实已经不是王二狗发出时的样子了,好死不死的牛翠花用的是mac,邮件客户端也自作聪明,又给处理了好多byte。这最后导致的就是使用UTF-8
解码失败,或者解出来的内容不对。
如果是英文文本还好一点,因为被处理的都是那些ASIIC中不可见字符,那些话还是可以出来的,如果是张图片,牛翠花可能就打不开了。
所以,Base64就是为了解决各系统以及传输协议中二进制不兼容的问题而生的。为啥Base64大家就兼容了呢?因为Base64满足了各方的需求,各方说了,俺们只保证支持ASIIC中那些基础字符,其他的俺们不能保证,于是Base64就去从那些基础字符里挑了64个,所以大家都高兴了。
目前由于传输导致的二进制改变已经很少见了,各种系统对二进制的兼容性处理也越来越好。假如你告诉我这一串01是一张jpg格式的图片,那我就按照jpg算法将其恢复成一张jpg图片,所以大家都很高兴。
地球人都知道计算机是欧美那帮人发明的,关键是这帮老外说的是英语,总共就26个字母。某天一个老外在认真的设计ASIIC码,他候低头看了一眼手中的键盘,数了数按键,思考了一下,若有所思的加入了一些控制符,最后凑了128个字符(后来进行了扩展),搞定收工!我日,他把我们说汉语的直接忽略了…因为人家肯定是只想着自己的文字啊,他们可能在想:什么?中国人也有可能用电脑吗?他们有电脑吗?到时候说英语好啦,汉字就不要用了
中国近150年来那叫一个矬B啊,落后愚昧,谁都能欺负。曾经的精英阶层(无论国共)均认为是中国的传统文化,以及汉语的复杂性导致了中国的全面衰落,大力提倡了汉字拉丁化,破四旧等等。足见咱们国家当年是多么的贫穷落后,把人的精神都逼成啥样了,准备放弃自己的文化了,但我们的祖国在近20年内迅速崛起了,虽然与西方仍然有较大的差距,但我们看到了光明的未来,这一点确实要感谢中国共产党。近年来文化也开始自信了,孔子学院也开到国外了,汉字也上了太空了,大部分妇女看到洋垃圾也不急着往回家捡了…
这里只做简单介绍,详情请参考相关技术文档
使用 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字符末尾会看到=
,有时1个,有时2个,这是为啥?
通过上面的我们知道了Base64编码过程是3个字符一组的进行,如果原文长度不是3的倍数怎么办呢?
例如我们的原文为Ma
,它不够3个,那么只能在编码后的字符串中补=
了。缺一个字符补一个,缺两个补两个即可,所以有时候你会看见base64字符串结尾有1个或者2个=
。
有时你会发现web页面传给你的base64字符串前面有类似下面的东东。
data:image/jpeg;base64, /9j/4AA...
这是DataURI,大部分浏览器支持直接打开这类二进制数据,但是我们要格外注意,如果你只是想要真实的Base64内容就需要取,
后边的内容
Java8终于支持了base64的编码和解码,使用方法也很简单。
即将文本或者二进制内容转换为base64字符串
例如我要将ShuSheng007
这段文本转换为base64的byte数组,如果你想要base64的字符串,直接将其转换为String即可。其实Java还为我们提供了一个包装方法encodeToString(byte[])
,使用其可以直接的到base64字符串
byte[] encodeBytes= Base64.getEncoder().encode("ShuSheng007".getBytes(StandardCharsets.UTF_8));
解码与编码使用方式一样。
byte[] decodeBytes = Base64.getDecoder().decode("U2h1U2hlbmcwMDc=".getBytes(StandardCharsets.UTF_8));
这次的解码方法就只能获得byte[]
了,因为要解码的base64字符串可以是任何内容,文本,图片,视频…
至此你已经可以使用Java进行Base64的编码与解码了。我其实在最开始接触base64编码时是很懵逼的:就拿这个解码来说吧,我不太明白为什么要从一个byte[]
转换为另一个byte[]
呢?当系统的学习后才恍然大悟。不知少年你首次接触base64编码时候有没有这些问题,如果没有说明你真的很有编程天赋,加油…
想不到一个Base64也能唠出这么多道道,真的是学海无涯啊。小伙伴记得点赞支持我啊