什么是Base64算法?——全网最详细讲解

                             什么是Base64算法?

 

 

一、何为Base64算法


Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方为64,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Za-z数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。

Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME电子邮件XML的一些复杂数据。

 

二、Base64算法是如何设计的


在不同的实现中,Base64算法中由64个字符组成的字符集是不一样的。但是通常的实现方法是选择64个通用且能打印的字符来组成这样一个集合。且要保证这个集合中的每个字符组成的数据在数据传输系统中不会被修改。

早期的Base64算法是用来实现运行相同操作系统之间进行拨号操作而创建的。

让我们先来看一下最通常的Base64索引表:

 

Bas64算法的实现


接下来,我们将使用ASCII文本来作为例子讲解,但是这并不是Base64最主流的用法。Base64算法生成的字符串可以安全地在任何实现了Base64算法的计算机之间传输。Base64典型的用途是给二进制数据(例如:图片文件)进行编码的,我们为了简化,就不用二进制,而是使用一段ASCII文本字符串来作为例子进行讲解。Base64编码出来的数据只会包含最多64种不同的ASCII字符,因此,使用Base64算法,我们就能避免数据在部分系统传输过程中发生改变。

例如,下面是一段ASCII文本组成的名言,我们将用这段名言来作为需要编码的输入样例:

Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.

我们可以先使用一些在线的Base64编码工具对这段文字进行Base64编码,这里推荐站长工具网上的Base64加密解密工具:http://tool.chinaz.com/Tools/Base64.aspx

我们对这段文本进行Base64编码后,得到的字符串为:

首先,我们发现字符串“Man”的Base64编码是“TWFu”,那么这是怎么转换过来的呢?不急,我们一个一个字符来分析,首先对于“M”来说,"M"对应的ASCII编码是77,二进制形式即01001101;同理,字符“a”对应的ASCII编码是97,二进制表现形式为01100001;“n”的ASCII编码为110,二进制形式为:01101110。(ASCII编码表可参考:http://tool.oschina.net/commons?type=4)这三个字符的二进制位组合在一起就变成了一个24位的字符串“010011010110000101101110”,接下来,我们从左至右,每次抽取6位作为1组(因为6位一共有2^6=64种不同的组合),因此每一组的6位又代表一个数字(0~63),接下来,我们查看索引表,找到这个数字对应的字符,就是我们最后的结果,是不是很简单呢?

例如下图所示,可能会看的更加明白一些:

24位字符串:“010011010110000101101110”的第一组6位数是“010011”,对应的十进制数是19,我们查找索引表发现,19对应的字符是“T”,因此,第一组6位数对应的字符就是“T”;同理,第二组6位数是“010110”,对应的十进制数是22,查找索引表,22对应的字符是“W”;同理,第三组6位数是“000101”,对应的十进制是5,查表得,5对应的字符是“F”;同理,第四组6位数是“101110”,对应的十进制是46,查表得,46对应的字符是“F”。到此,“Man”字符串的编码就完成了,不相信的同学可以去上述的Base64在线加密网站亲自试一试。我们发现,3个ASCII字符,一共24位,最后编码成了4个ASCII字符,32位。因此,从24位到32位的转变,使得Base64编码的结果要比原来的值变得更大,且大1/3。因此,Base64编码实质上就是把一个个24比特位组成的二进制组合转换成32比特位组成的二进制组合。

当然,如果思考的周密的同学肯定会想到,万一我只有2个ASCII字符需要进行Base64编码,这两个字符一共才16位,并不是6的倍数啊!并且也不够24位啊!那怎么分组呢?不够分啊,即使第一组占前6位,第二组占6位,剩下的4位也不够凑成一组啊!并且还有最后6位怎么办?

不急,Base64的设计者早就想到了这一点,如若是少了“位”,即使用0填充。若是少了一组,直接用“=”代替。

例如,我们假设需要编码的字符串为“Ma”,我们把他们转换为相应的二进制:

 首先,仍然是老规矩:第一组6位数是“010011”,对应的十进制数是19,我们查找索引表发现,19对应的字符是“T”;第二组6位数是“010011”,对应的十进制数是22,我们查找索引表发现,19对应的字符是“W”,第三组。。。。哦,第三组貌似不够6位啊,只有4位,那么剩下的2位自动填充为0,则第三组6位数是“000100”,对应的十进制数是4,我们查找索引表发现,4对应的字符是“E”,但是我们发现,最后6位根本啥都没有啊!不要急,对于这种情况,我们直接用“=”代替空的6个比特位。

因此,"Ma"的Base64编码结果就是“TWE=”,不信可以亲自试试(注意大小写):http://tool.chinaz.com/Tools/Base64.aspx

既然3个字符(24位)才够转换为4个6位的分组。那么如果我只有1个ASCII字符怎么办呢?例如,我们对字符“M”进行Base64编码操作:

 同理,字符“M”只有8位,根本不够24位凑成一组。那么我们仍然先来解析第一组的6位,第一组6位数是“010011”,对应的十进制数是19,我们查找索引表发现,19对应的字符是“T”,第二组只有2位,剩下的4位按照老规矩置0,则第二组6位数是“010000”,对应的十进制数是16,我们查找索引表发现,16对应的字符是“Q”,第3组没有任何二进制位,直接用“=”代替,同理,第4组也没有任何二进制位,用“=”代替。

因此,"Ma"的Base64编码结果就是“TQ==”,不信可以亲自试试(注意大小写):http://tool.chinaz.com/Tools/Base64.aspx

基于“=”的填充机制,我们可以通过观察Base64编码的字符串最后有几个“=”来判断最后一组24位中有几个“填充字节”。

如果有1个“==”,则最后1组包含2个ASCII字符。如果有两个“=”,则最后一组只包含1个ASCII字符。

因此,通过这样的Base64转换,我们可以得到这样的一个结论:Base64的输出与输入比是4:3。特别的,当输入是n个字节时(1个字节等于8位),输出会是(4/3)*n个字节。

理论上来说,当我们对Base64进行解码时,填充符号“=”是不用考虑进去的。但是在一些实现中,填充符号“=”是必须的,一种情况是连接多个Base64编码的字符串,如果不使用填充字符“=”,则在解码时将会发生错误。

接下来,我们在看一段动画演示上述的完整编码过程:(点击全屏观看)

 

参考资料


【1】维基百科——Base64编码 

 

文章版权声明


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值