1.什么是BASE64编码?
BASE64是网络上最常见的用于传输8bit字节码的编码方式之一,是一种基于64个可打印字符来表示二进制数据的方法。
解决什么问题?
表示从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。同时具有不可读性,需要解码才可阅读,有一定保密性。
2.了解编码过程:
1.将目标通过ASCII编码转化为二进制字符串,即00110010 00110000 00110010 00110000 00110001 00110010 00110001 00110000
2.将字符串按顺序每24bit为一组,不足则补0使其为24bit,每一组中每六个字符分为一小组,得到
001100 | 100011 | 000000 | 110010 | 001100 | 000011 | 000100 | 110010 | 001100 | 010011 | 000000 | 000000 |
3.将每组的六个字符前补上两个0,使其扩展为8bit,得到
00001100 | 00100011 | 00000000 | 00110010 | 00001100 | 00000011 | 00000100 | 00110010 | 00001100 | 00010011 | 00000000 | 00000000 |
4.根据base索引表进行编码,结尾的全零组用 “ = ” 表示,得到
00001100 | 00100011 | 00000000 | 00110010 | 00001100 | 00000011 | 00000100 | 00110010 | 00001100 | 00010011 | 00000000 | 00000000 |
12 | 35 | 0 | 50 | 12 | 3 | 4 | 50 | 12 | 3 | 4 | 结尾 |
M | j | A | y | M | D | E | y | M | D | E | = |
由此可得,我的学号20201210的编码为MjAyMDEyMTA=
姓名徐铭泽的编码为eHVtaW5nemU=
解码过程反过来即可
3.编码的python实现
-
import base64 #内部库验证
-
base_chrs = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-
chrsdic = dict(zip(base_chrs, range(64)))
-
-
-
def bs64encode(src):
-
"""将源数据按base64编码
-
-
:param src:bytes
-
:return: bytes
-
"""
-
ret = bytearray()
-
r = 0
-
for i in range(0, len(src), 3):
-
block = src[i:i+3] #切片,超界也无所谓
-
if len(block) < 3:
-
r = 3 - len(block)
-
block += b'x00' * r #用x00补齐位数
-
num = int.from_bytes(block, 'big')
-
for j in range(4):
-
k = (4-j-1)*6
-
c = (num >> k) & 0x3f
-
ret.append(base_chrs[c])
-
for i in range(1, r+1):
-
ret[-i] = int.from_bytes(b'=', 'big')
-
return bytes(ret)
-
-
-
def bs64decode(src):
-
"""解码base64编码数据
-
-
:param src: bytes
-
:return: bytes
-
"""
-
ret = bytearray()
-
for i in range(0, len(src), 4):
-
block = src[i:i+4]
-
tmp = 0x00
-
cnt = 0
-
for j in range(4):
-
index = chrsdic.get(block[-j-1]) #get找不到返回None,用负索引,j就是要移动的位数
-
if index is not None:
-
tmp += index << j*6
-
else: #None就是遇到最后的b'=',为0,所以不用移位
-
cnt += 1
-
num = tmp.to_bytes(3, 'big') # int.to_bytes()
-
ret.extend(num) #bytearray 为list,方法通用
-
for k in range(cnt):
-
ret.pop()
-
return bytes(ret)