简短回答
您需要将一个“类字节”对象(bytes
,bytearray
等)推送到base64.b64encode()
方法中。以下是两种方法:
>>> import base64
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
或使用变量:
>>> import base64
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
为什么?
在Python 3中,str
对象不是C风格的字符数组(因此它们不是字节数组),而是没有任何固有编码的数据结构。您可以用多种方式对该字符串进行编码(或解释)。最常见的(也是Python 3中的默认值)是utf-8,特别是因为它向后兼容ASCII(尽管大多数广泛使用的编码都是如此)。当您获取一个string
并在其上调用.encode()
方法时,就会发生这种情况:Python正在以utf-8(默认编码)解释字符串,并为您提供相应的字节数组。
Python 3中的Base-64编码
最初,问题标题询问Base-64编码。请继续阅读Base-64内容。
"base64"编码将6位二进制块使用字符A-Z、a-z、0-9、'+'、'/'和'='(某些编码在'+'和'/'的位置使用不同的字符)进行编码。这是一种基于数学构造的基数64或base-64数字系统的字符编码,但它们非常不同。在数学中,Base-64是像二进制或十进制一样的数字系统,你可以对整个数字进行基数转换,或者(如果你要从的基数是小于64的2的幂),从右到左分块进行转换。
在"base64"编码中,翻译是从左到右进行的;那前64个字符就是为什么它被称为"base64"编码。第65个'='符号用于填充,因为编码提取6位块,但通常要编码的数据是8位字节,所以最后一个块中有时只有两个或四个位。
例子:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
如果您将二进制数据解释为一个整数,那么您可以将其转换为十进制和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
字符,电子邮件就会立即发送,因为这是ASCII的END-OF-TRANSMISSION
(Ctrl-D),因此剩余数据将被遗漏。
- 而且,虽然Python足够聪明以直接打印数据时转义所有恶意控制字符,但是当该字符串解码为ASCII时,您可以看到'msg'不存在。这是因为我使用了三个
BACKSPACE
字符和三个SPACE
字符来擦除'msg'。因此,即使我没有EOF
字符,最终用户也无法从屏幕上的文本转换为真正的原始数据。
这只是一个演示,向您展示简单发送原始数据有多困难。将数据编码为base64格式可以给您提供完全相同的数据,但以确保其安全发送到电子媒体(例如电子邮件)的格式。