Base64背景
维基百科的解释
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2^6^=64,所以每6个bit为一个单元,对应某个可打印字符。3个字节有24个bit,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母
A-Z
、a-z
、数字0-9
,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。
由来及场景
在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现乱码情况。与此类似,网络上传输的字符并不全是可打印的字符,比如二进制文件、图片等。Base64的出现就是为了解决此问题,它是基于64个可打印的字符来表示二进制的数据的一种方法。
电子邮件刚问世的时候,只能传输英文,但后来随着用户的增加,中文、日文等文字的用户也有需求,但这些字符并不能被服务器或网关有效处理,因此Base64就登场了。随之,Base64在URL、Cookie、网页传输少量二进制文件中也有相应的使用。
通常使用的字符
使用的字符包括大小写英文字母各26个、数字10个、加号
+
和斜杠/
,共64个字符,等号=
用来作为后缀用途。
算法简介
编码过程
- 通常情况
- 将待编码的字符串中各个字母的ASCII码查出.
- 将ASCII码转化为8位2进制表示,如文本M的ASCII码为
77
,用二进制表示则为01001101
. - 由于每6个bit为一个单元,所以每6个二进制位转化成一个十进制数,即编码结果的ASCII码. 如
010011
计算可得19
. - 转化所有编码结果即可.
- 当字节不能被3整除时:
- 当无法被整除时,base64要在后面添加
\0
凑齐3n
位,使二进制序列的长度成为24
的倍数(6和8的最小公倍数). - 由于不断补
0
,对应产生的空字符将用等号=
填充,所以等号的个数必为0个,1个或2个.
其他场景
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的
/
和+
字符变为形如%XX
的形式,而这些%
号在存入数据库时还需要再进行转换,因为ANSI SQL中已将%
号用作通配符。1 2 3 4 5 6
import base64 encode_str = base64.b64encode('ac>'.encode('utf-8')) print("result: ", encode_str) url_safe_encode_str = base64.urlsafe_b64encode('ac>'.encode('utf-8')) print("result: ", url_safe_encode_str)
运行结果:
1 2 3 4 5
[Running] python -u "d:\urlsafe.py" result: b'YWM+' result: b'YWM-' [Done] exited with code=0 in 0.424 seconds
解码过程
去掉末尾的等号=
。剩下的Base64字符,每8bit组成一个8bit字节,最后剩余不足8位的丢弃.
总结
一般来说,由于使用base64编码后的长度通常是原字符长度的4/3
倍.
其实在补0
的问题上,我也疑惑过为什么要一直补到24
的倍数. 实际上这样做不仅是实现上的问题,而且当两个编码结果进行拼接之后,解码过程也能顺利进行.这样一想,应该就能很好理解了.