利用Python实现Base64

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。 ——维基百科

Base64可谓是一种比较常见的编码了,也可以通过Base64 对信息的一些简单的加密。根据维基百科上的说明可以分为以下步骤,获取字符的二进制。然后通过二进制以6位分割转为十进制,然后通过十进制数字从Base64索引表里面获取加密后的字符,话不多说开始搞

获取二进制

在Python中获取字符的二进制,获取二进制首先需要获得字符ASCLL值,然后通过ASCLL值转为二进制,例如‘a’的ASCLL值是97。这个可以通过ord()获取

>>> ord('a')
97

然后通过获取的ASCLL获取二进制

>>> bin(97)
'0b1100001'

八位二进制

在Python中使用0b和-0b区分正负数,例如bin(-97)获得就是-0b1100001,哈哈哈哈,好像偏了😅,不过对于Base64来说需要对二进制进行格式化,变成8位的。例如0b1100001需要格式化成01100001,不满8位的需要在高位补0,直到补足8位,这个时候我们不需要ob用来区分正负数了,在ASCLL码值中是没有负数的。

def binaryFormat(c):
    b = c.replace('0b', '') # 替换 0b
    a = 8 - len(b) # 获取长度以及缺少位数
    while a:
        b = "0" + b
        a = a - 1
    return b

补位

这个返回的是一个8位的二进制字符串。通过上面的代码a最终的二进制是01100001,可以进行下一步了,把二进制按6位分割,不足补0,现在先把位置补足

def binaryFormatSix(bit):
    print(-2152 % 6 )
    lenght = -len(bit) % 6 / 2 # 1 代表两个0
    print(lenght)
    count  = lenght
    while count:
        bit = bit + '00'
        count = count - 1
    return bit,lenght

因为lenght这个后面需要用到,所以返回两个值,对于 -len(bit) % 6 / 2我暂时无法解释,可能是优先级问题吧,hhhhh,😂,正常代码应是这样,到这一步 a 变成011000010000

def binaryFormatSix(bit):
    print(-2152 % 6)
    lenght = 0
    if len(bit) % 6:
        lenght = (6 - len(bit) % 6) / 2  # 1 代表两个0
    print(lenght)
    count = lenght
    while count:
        bit = bit + '00'
        count = count - 1
    return bit, lenght

到了这里差不多就剩最后一步了。把返回的二进制按6位分割,然后进行十进制转化。再从base64索引中获取字符。

base64索引表

数值 字符 数值 字符 数值 字符 数值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

根据上面的索引表建立字典

keystr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

最后根据字典写出实现代码

def base64(bit):
    keystr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    bit, count = binaryFormatSix(bit)
    base64str = ""
    for i in range(0, len(bit), 6):
        l = bit[i:i + 6]
        base64str = base64str + keystr[int(l, 2)]
    print(base64str)
    while count:
        base64str = base64str + '='
        count = count - 1
    return base64str

q.png

最后因为补位4个,需要添加两个==,所以最终是YQ==
完整代码实现

# coding:utf-8

def binaryFormat(c):
    b = c.replace('0b', '')
    a = 8 - len(b)
    while a:
        b = "0" + b
        a = a - 1
    return b

def binaryFormatSix(bit):
    lenght = 0
    if len(bit) % 6:
        lenght = (6 - len(bit) % 6) / 2  # 1 代表两个0
    count = lenght
    while count:
        bit = bit + '00'
        count = count - 1
    return bit, lenght

def base64(bit):
    keystr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    bit, count = binaryFormatSix(bit)
    base64str = ""
    for i in range(0, len(bit), 6):
        l = bit[i:i + 6]
        base64str = base64str + keystr[int(l, 2)]
    while count:
        base64str = base64str + '='
        count = count - 1
    return base64str

if __name__ == '__main__':
    text = "a"  # 需要Base64编码的文本
    bit = ""  # 存放二进制
    for i in text:
        c = bin(ord(i))
        bit = bit + binaryFormat(c)
    print(base64(bit))