简短答案
你需要一个推bytes-like
对象(bytes
,bytearray
,等)的base64.b64encode()
方法。有两种方法:
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
或带有变量:
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
为什么?
在Python 3中,str
对象不是C样式的字符数组(因此它们不是字节数组),而是对象,它们是没有任何固有编码的数据结构。您可以通过多种方式对该字符串进行编码(或解释)。最常见的(也是Python 3中的默认设置)是utf-8,特别是因为它与ASCII向后兼容(尽管使用最广泛的编码也是如此)。那就是当您采用a string
并对其调用.encode()
方法时发生的事情:Python正在以utf-8(默认编码)解释字符串,并为您提供与其对应的字节数组。
Python 3中的Base-64编码
最初,问题标题是关于Base-64编码的。继续阅读有关Base-64的内容。
base64
编码采用6位二进制块,并使用字符AZ,az,0-9,'+','/'和'='进行编码(某些编码使用不同的字符代替“ +”和“ /”) 。这是基于基数64或基数64的数字系统的数学构造的字符编码,但它们有很大的不同。数学中的Base-64是一个数字系统,如二进制或十进制,您可以对整个数字进行基数的这种更改,或者(如果要转换的基数是2的乘方小于64,则从右到大)剩下。
在base64
编码中,翻译是从左到右完成的;前64个字符就是为什么称其为base64
编码的原因。第65个“ =”符号用于填充,因为编码会提取6位块,但是通常要编码的数据是8位字节,因此有时最后一块中只有2位或4位。
例:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
如果将二进制数据解释为单个整数,则可以通过以下方法将其转换为base-10和base-64(base-64 表):
base-2: 01 110100 011001 010111 001101 110100 (base-64 grouping shown)
base-10: 1952805748
base-64: B 0 Z X N 0
base64
编码,但是,将因此重新分组此数据:
base-2: 011101 000110 010101 110011 011101 00(0000) <- pad w/zeros to make a clean 6-bit chunk
base-10: 29 6 21 51 29 0
base-64: d G V z d A
因此,从数学上来说,“ B0ZXN0”是我们二进制文件的base-64版本。但是,base64
编码必须沿相反方向进行编码(因此原始数据将转换为“ dGVzdA”),并且还具有一条规则来告诉其他应用程序最后还剩下多少空间。这是通过在末尾添加'='符号来完成的。因此,base64
此数据的编码为“ dGVzdA ==”,带有两个“ =”符号以表示当解码该数据以使其与原始数据匹配时,需要从末端删除两对位。
让我们测试一下,看看我是否不诚实:
>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='
为什么要使用base64
编码?
假设我必须通过电子邮件将一些数据发送给某人,例如以下数据:
>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())
>>> print(data)
b'\x04msg\x08\x08\x08 '
>>>
我植入了两个问题:
- 如果我尝试在Unix上发送该电子邮件,则该电子邮件将
\x04
在读取字符后立即发送,因为END-OF-TRANSMISSION
(Ctrl-D)为ASCII ,因此其余数据将不发送。
- 同样,虽然Python足够聪明,可以在我直接打印数据时转义我所有的邪恶控制字符,但是当该字符串被解码为ASCII时,您可以看到'msg'不存在。那是因为我使用了三个
BACKSPACE
字符和三个SPACE
字符来擦除“ msg”。因此,即使我在EOF
那里没有字符,最终用户也无法将屏幕上的文本转换为真实的原始数据。
这只是一个演示,向您展示简单发送原始数据有多困难。将数据编码为base64格式可为您提供完全相同的数据,但格式应确保可以安全地通过电子媒体(如电子邮件)发送。