Skip to content

Instantly share code, notes, and snippets.

@j178
Created August 31, 2017 12:19
Show Gist options
  • Save j178/eb33cddcdd4348e76684aa4d1d64910f to your computer and use it in GitHub Desktop.
Save j178/eb33cddcdd4348e76684aa4d1d64910f to your computer and use it in GitHub Desktop.
Reinvent the wheel: implemente base64 encoding and decoing in Python.
CHARS = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
NUMS = [62, 0, 0, 0, 63,
*range(52, 62),
0, 0, 0, 0, 0, 0, 0,
*range(26),
0, 0, 0, 0, 0, 0,
*range(26, 52)]
def to_val(c):
return NUMS[c - ord('+')]
def group(s, step):
i = 0
while i + step < len(s):
yield s[i:i + step]
i += step
yield list(s[i:]) + [0 for _ in range(i + step - len(s))]
def base64_encode(s):
rv = []
for i, j, k in group(s, 3):
a = i >> 2
b = ((i & 0b11) << 4) + (j >> 4)
c = ((j & 0b1111) << 2) + (k >> 6)
d = k & 0b111111
rv.extend([CHARS[a], CHARS[b], CHARS[c], CHARS[d]])
# 最后的 A 或者 AA 需要替换为 =
# 如果 Base64 编码字符串不会相互拼接在传输,最后的=也可以省略。
# 在解码时发现长度不能被4整除,则先补充=号,再解码。
if len(s) % 3:
for i in range(3 - len(s) % 3):
rv[-(i + 1)] = ord('=')
return bytes(rv)
def base64_decode(s):
nequal = len(s) - s.find(b'=')
rv = []
for a, b, c, d in group(s, 4):
a, b, c, d = to_val(a), to_val(b), to_val(c), to_val(d)
i = (a << 2) + (b >> 4)
j = ((b & 0b1111) << 4) + (c >> 2)
k = ((c & 0b11) << 6) + d
rv.extend([i, j, k])
for _ in range(nequal):
rv.pop()
return bytes(rv)
if __name__ == '__main__':
print(base64_decode(b'YQ=='))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment