最近学Python的时候遇到了编码问题,顺带了解了一下base64编码,首先阅读了咱CSDN上的一篇文章Base64编码原理,有所感悟,记录下来以备日后查看
首先,base64编码是用64个字符来表示任意二进制的数据的方法,有时候我们用记事本打开.pdf,.exe, .png的后缀名的文件时打开是一堆乱码。实际上这些二进制文件里面包含了许多无法打印的字符,如果我们让记事本能处理打开这些文件,就需要一种能处理二进制文件到字符串的转换的方法,就用到了base64编码。
它很简单,出现的原因也很单一:因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。
首先,准备一个包含64个字符的数组:['A', 'B', 'C', ... 'a','b', 'c', ... '0', '1', ... '+', '/'],换成图标来表示就是这样的
1字符=1个字节=1byte=8个bit,所以任意一个上图的64个字符中的都能用2的6次方以下的数来表示,换成二进制来看,任意一个base64编码的字符最多就是占位6个bit,但是规定就是一个字符等于8个bit啊,现在你用一个base64就叫我换成6个bit了,那我多下来的俩bit放哪里?那么怎么用6个有效bit来表示传统字符的8个bit呢?8和6的最小公倍数是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit的不足。你也可以说用两个Base64字符也能表示一个传统字符,但是采用最小公倍数的方案其实是最减少浪费的。结合下边的图比较容易理解。Man是三个字符,一共24个有效bit,只好用4个Base64字符来凑齐24个有效位。红框表示的是对应的Base64,6个有效位转化成相应的索引值再对应Base64字符表,查出"Man"对应的Base64字符是"TWFU"。说到这里有个原则不知道你发现了没有,要转换成Base64的最小单位就是三个字节,对一个字符串来说每次都是三个字节三个字节的转换,对应的是Base64的四个字节。这个搞清楚了其实就差不多了。
加密解密的时候,对字符换成ASCII码是第一步,可以看到,M换成ASCII码后是77,然后用二进制表示成01001101,a和n分别是01100001和01101110剩下的拼凑其实就是加减法了,很简单,对应字符的二进制码全放到一起,然后从头开始按6个bit是一个base64码的规则来截,转换成base64的字符后,最后剩下的如果不足6位,就用=号来补位。如果是6的倍数,那么编码结果就是base64的编码集结果的一堆字符,如果不是6的倍数,就要在后面补位‘=’,凑够6位为止,例如我们通常下载的迅雷链接,使用的就是对地址进行base64位加密,通常能在链接的最后面看到‘=’,就是这个原因了
说起Base64编码可能有些奇怪,因为大多数的编码都是由字符转化成二进制的过程,而从二进制转成字符的过程称为解码。而Base64的概念就恰好反了,由二进制转到字符称为编码,由字符到二进制称为解码。
Base64编码主要用在传输、存储、表示二进制等领域,还可以用来加密,但是这种加密比较简单,只是一眼看上去不知道什么内容罢了,当然也可以对Base64的字符序列进行定制来进行加密。
其他文章请移步个人博客:http://zhangqq166.cn/