Base64编码和解码原理

Base64常用于对电子邮件、短信、URL等进行编码和传输,在Python和Mysql中都有实现方式

但这里要说的是它编码的基本原理和步骤。

1. 首先相信大家都会看到这个表:Base64对应的字符表,一共64个字符,包括26个字母的大小写、10个阿拉伯数字、+号和/号;附:(还有一个' =' 号一般用于后缀)。

2. Base64并不加密信息,因为它属于编码方式,不属于加密系统;可以随时对其信息进行解码。

3. Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64是一种基于上述64个可打印ASCII字符来表示二进制字节流数据的方法,还有' =' 号用于后缀。

Base64编码是一种从二进制到字符的过程,解码则相反。

4. 其编码规则主要有:

  • 把3个字节变成4个字节。
  • 每76个字符加一个换行符。
  • 结束符也要进行处理。

5. 编码步骤

(1)对原始数据,分字节,求二进制字符串;

(2)对二进制串,6位为一组进行分组,不足末尾补0;

(3)在各分组前面补2个0成8位,求各分组的十进制值,根据十进制对应上表找编码字符;

(4)字节数对3取余数,余数为0,不加等号;余数为1,在上述编码符号串的末尾加2个等号;余数为2,末尾加1个等号。

6. 编码示例

(1)原始数据是英文字符,sss = 'SE'

流程:

首先,求取 'SE' 的二进制编码(utf-8和ASCII等在英文时一致),sss.encode('utf-8') = b 'SE',b表示bytes类型,'SE'只是打印出来的符号,实际上其二进制是ASCII码的大写'S'和'E'的编码连接而成:01010011(二进制,其十进制是83,'S'),01000101(二进制,其十进制是69,'E')—— 即,将输入字符串按字节切分,取得每个字节对应的二进制值(若不足8比特则高位补0)

其次,将该二进制字符串:01010011 01000101,按照6位一组进行切分(因为2的6次方刚好是64,在Base64的编码范围内),最后一组如果不足6位则末尾补0;于是得到:010100 110100 010100 的3组二进制串。

然后,各自在前面补2个0得到:00010100 00110100 00010100,转化成十进制为:20,52,20;对应到上面的表中得到:'U0U',注意中间这个是0。

最后,将N字节的原始数据,每个字节8位,按照6位一组进行划分,(而6和8的最小公倍数为24),所以要划分的二进制位数必须是24的倍数(或者字节数是3的倍数),而这里的 'SE' 原始数据只有2个字节,2%3=2,所以在结尾需要补上1个等号 '='。

综合以上得到:'U0U='

:由于某字节数M%3的值,(即M除以3的余数)只有0,1,2共三种情形,0表示整除(不用加等号 '=');那么余数为1,则要加上2个等号 '=';余数为2则要加上1个等号 '='

(2)原始数据是中英文,sss='线?' ,这里的问号是英文

流程:

同理,首先求取sss字符串的二进制编码,sss.encode('utf-8') = b'\xe7\xba\xbf?',b表示bytes字节流类型,\x表示十六进制,写的清楚一点就是:e7 ba bf ?

则该字符串的二进制数据(进制转换)为:11100111(e7)10111010(ba)10111111(bf)00111111(英文?的ASCII码,二进制);

其次,将上述字符串6位一组进行划分,不足补0,得到:111001 111011 101010 111111 001111 110000;

然后各自在前面补2个0得到:00111001 00111011 00101010 00111111 00001111 00110000,十进制值也就是:57,59,42,63,15,48;对应上表也就是:'57q/Pw'

最后,原始数据共4个字节,4%3=1,所以加上两个等号 '='。

综合以上得到:'57q/Pw=='

import base64

sss = 'SE'
aaa = base64.b64encode(sss.encode('utf-8'))   #base64编码前,需要把数据变成字节流bytes
print('aaa:',aaa)

bbb = base64.b64decode(aaa)  #解码
print('bbb:',bbb)

7. 解码

解码就是编码的逆过程:

(1)先去掉等号;

(2)再根据编码表,找编码字符对应的编码值;

(3)取各编码值的8位二进制值,去掉每个二进制的前2位的0值,然后连接形成二进制串;

(4)对上述二进制串,从前到后,每8位构成一个字节的数据;多余的末尾0值去掉;

(5)此时得到的就是原始数据的二进制编码;再根据编码方式(例如 utf-8)等进行解码。

8. 解码示例

对于上述编码的 'U0U=':

首先,去掉等号 '=',得到 'U0U';

其次,根据编码表,找到对应的编码值:20,52,20;

然后,取8位二进制值为:00010100 00110100 00010100;每一个去掉前面2位的0,得到:010100 110100 010100;

最后,从前到后,每8位构成一个字节数据,去掉末尾多余的0:010100 110100 010100;所以末尾2个0去掉,此时得到的就是原始数据的二进制编码,可以继续utf-8解码形成原始数据;

# 欢迎交流

参考:

https://blog.csdn.net/u013412497/article/details/51552335

https://baike.baidu.com/item/base64/8545775?fr=aladdin

猜你喜欢

转载自www.cnblogs.com/qi-yuan-008/p/12940018.html