Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。 ——维基百科
Base64可谓是一种比较常见的编码了,也可以通过Base64 对信息的一些简单的加密。根据维基百科上的说明可以分为以下步骤,获取字符的二进制。然后通过二进制以6位分割转为十进制,然后通过十进制数字从Base64索引表里面获取加密后的字符,话不多说开始搞
获取二进制
在Python中获取字符的二进制,获取二进制首先需要获得字符ASCII值,然后通过ASCII值转为二进制,例如‘a’的ASCII值是97。这个可以通过ord()获取
>>> ord('a')
97
然后通过获取的ASCII获取二进制
>>> bin(97)
'0b1100001'
八位二进制
在Python中使用0b和-0b区分正负数,例如bin(-97)
获得就是-0b1100001
,哈哈哈哈,好像偏了😅,不过对于Base64来说需要对二进制进行格式化,变成8位的。例如0b1100001
需要格式化成01100001
,不满8位的需要在高位补0,直到补足8位,这个时候我们不需要ob用来区分正负数了,在ASCII码值中是没有负数的。
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
最后因为补位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))