赞
踩
1. 什么是 base64 编码
2. 举例说明
3. 如何用 Python 实现
4. 具体代码
5. 代码运行展示
6. 更简单的代码
7. 心得总结
对于任意的二进制文件,可用 base64 编码。这种编码方法是先把二进制代码划分为一个个 24 位长的单元,然后把每一个 24 位单元划分为 4 个 6 位组。每一个 6 位组按以下方法转换为 ASCII 码。6 位的二进制码共有 64 种不同的值,从 0 到 63。用 A 表示 0,用 B 表示 1,等等。26 个大写字母排列完毕之后,接下去再排 26 个小写字母,在后面是 10 个数字。最后用 “+” 表示 62,用 “/” 表示 63。再用两个连在一起的等号 “==” 和 一个等号 “=” 分别表示最后一组的代码只有 8 位或 16 位。回车和换行都忽略,它们可在任何地方插入。 —— 摘自 《计算机网络(第7版)》
简单点说,就是每个字节变为 8 位二进制,拼在一起,其中每 6 位转变为一个 ASCII 码,不足位填充 0 直至满足 6 位的条件,继续转变为 ASCII 码。将这些二进制 ASCII 码变为十进制,接着查找 base64 编码表,所得的结果组成的字符串就是 base64 编码的结果,不足 4 的倍数,末尾添加 = 。通过 base64 编码,只需要用简单的 ascii 码,就能表示繁多的二进制文件中复杂的数据。
那么,该如何用 Python 实现这些步骤呢?
让我们一步一步解决问题【假设我们已经获得一个字符串】:
1. 想办法将字符串中所有的内容变为十进制
(1)ascii 码,可以直接通过内置函数完成:
>>>a = "A"
>>>b = ord(a)
>>>b
>65
(2)非 ascii 码,通过编码:
>>>a = '哔哩哔哩弹幕网'
>>>b = a.encode('utf-8')
>>>b
>b'\xe5\x93\x94\xe5\x93\xa9\xe5\x93\x94\xe5\x93\xa9\xe5\xbc\xb9\xe5\xb9\x95\xe7\xbd\x91'
可以得到一连串的 16 进制码,\x
后面的两个字符,就是十六进制后的结果。
接下来,我们就要尝试把这些 16 进制的内容,变为十进制数字,用内置函数 list 直接转换为十进制列表:
>>>a = '哔哩哔哩弹幕网'
>>>b = a.encode('utf-8')
>>>list(b)
>[229, 147, 148, 229, 147, 169, 229, 147, 148, 229, 147, 169, 229, 188, 185, 229, 185, 149, 231, 189, 145]
这就很方便了。
2. 将十进制数字转换为二进制
>>>b = 10
>>>str(bin(b))[2:]
>'1010'
3. 经过我的研究,要将不足8位的二进制,填充为 8 位二进制
>>>a = '11000'
>>>a.zfill(8)
>'00001100'
4. 拼接二进制字符串,并填充二进制字符串为 6 的倍数,用 0 填充
方法很多我就不多介绍了。
5. 划分二进制字符串,6 位为一个单元
6. 将 6 位二进制串,转换为十进制数字,并查找 base64 编码表
>>>a = '10'
>>>b = int(a, 2)
>>>b
>2
查找 base64 编码表,可以通过创建一个键值对应的字典,来实现查找内容,如果不想手动行行输入的话,尝试用编程解决 base64 编码表生成的问题,比如:
string_temp = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz'
'0123456789+/')
base64_dict = {}
for i in range(2**6):
base64_dict[i] = string_temp[i]
7. 查完表后,组成字符串,检查是否为 4 的倍数,不足填充 = ,直到满足 4 的倍数为止。
因为简单的 base64 编码或其他情况,会因为不足 4 的倍数,而填充 = ,因此我们这里也要实现填充 = 的功能
到此,base64 编码也就是实现完成,接下来用具体的代码,来完成上面的步骤。
测试例子:哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
,ascii + 非 ascii:
class MyBase64(): base64_dict = {} string_temp = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' '0123456789+/') ascii_string = ''.join([chr(i) for i in range(4, 2**7-1)]) def __init__(self, string): # 初始化,创建 base64 编码字典 self.string = string for i in range(2**6): self.base64_dict[i] = self.string_temp[i] def convert(self): # base64 编码过程 # 编码 string_encode_byte = self.string.encode('utf-8') # 十进制化 string_digit_list = list(string_encode_byte) # 二进制化 + 0 填充 string_bin_list = [] for item in string_digit_list: string_bin_list.append(str(bin(item))[2:].zfill(8)) # 字符串合并 string_sum = ''.join(string_bin_list) # 6 的倍数,不足 0 填充 string_fill = self.fillIt(string_sum, factor=6, item='0') # 切片,6位一个单位 string_bin_list2 = self.splitIt(string_fill, bits=6) # 十进制化 string_digit_list2 = [] for item in string_bin_list2: string_digit_list2.append(int(item, 2)) # 查表 string_base64_list = [] for item in string_digit_list2: string_base64_list.append(self.base64_dict[item]) # 拼接 string_sum2 = ''.join(string_base64_list) # 4 的倍数,不足填充 = string_convert = self.fillIt(string_sum2, factor=4, item='=') return string_convert def fillIt(self, string, factor, item): """ 指定倍数填充指定字符 string:原字符串 factor:倍数 item:填充字符 """ length = len(string) remainder = length % factor if remainder: times = factor - remainder string = string + times * item return string def splitIt(self, string, bits): """ 指定位数切片 string:原字符串 bits:每次切片数量 """ length = len(string) new_list = [] for i in range(bits, length+1, bits): new_list.append(string[i-bits:i]) remain = length % bits if remain != 0: new_list.append(string[-remain:]) return new_list if __name__ == '__main__': test_string = '哔哩哔哩 (゜-゜)つロ 干杯~-bilibili' myBase64 = MyBase64(test_string) string = myBase64.convert() print("测试字符串:{}".format(test_string)) print("base64:{}".format(string))
其实 Python 自带了 base64 编码的库:
import base64
s = '哔哩哔哩 (゜-゜)つロ 干杯~-bilibili'.encode()
a = base64.b64encode(s)
print(a)
base64 库,可以方便地将原字符串转变为 base64 编码后的结果。
虽然有 base64 库,可以方便的编码,但是知道了 base64 编码到底是怎么回事之后,对它的掌握将更加的随心所欲。而且,Python 编码确实是个头疼的问题。在这次实现 base64 过程中,我们就能发现,能深入浅出的懂得如何使用 Python 的编码也是一件很重要的事情。
Fin.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。