📜  在Python中编码和解码Base64字符串

📅  最后修改于: 2020-08-27 08:49:48             🧑  作者: Mango

介绍

您是否曾经通过电子邮件收到某人提供的PDF或图像文件,但在打开时却看到了奇怪的字符?如果您的电子邮件服务器仅设计为处理文本数据,则可能会发生这种情况。具有二进制数据的文件(表示图像之类的非文本信息的字节)在传输和处理到纯文本系统时很容易损坏。

Base64编码允许我们将包含二进制或文本数据的字节转换为ASCII字符。通过对数据进行编码,我们提高了各种系统正确处理数据的机会。

在本教程中,我们将学习Base64编码和解码的工作原理以及如何使用它。然后,我们将使用Python对Base64编码和解码文本和二进制数据。

什么是Base64编码?

Base64编码是将字节转换为ASCII字符的一种类型。在数学中,数字系统的基础是指多少个不同的字符代表数字。这种编码的名称直接来自碱基的数学定义-我们有64个代表数字的字符。

Base64字符集包含:

  • 26个大写字母
  • 26个小写字母
  • 10个数字
  • +/换行(某些实现可能使用不同的字符)

当计算机将Base64字符转换为二进制时,每个Base64字符代表6位信息。

注意:这不是加密算法,不应出于安全目的使用。

现在我们知道了Base64编码是什么以及如何在计算机上表示,让我们更深入地研究它的工作方式。

Base64编码如何工作?

我们将通过转换文本数据来说明Base64编码是如何工作的,因为它比各种二进制格式更标准。如果我们要对Base64编码一个字符串,我们将遵循以下步骤:

  1. 取字符串中每个字符的ASCII值
  2. 计算ASCII值的8位二进制等效项
  3. 只需重新组合数字,即可将8位块转换为6位块
  4. 将6位二进制组转换为其各自的十进制值。
  5. 使用base64编码表,为每个十进制值分配相应的base64字符。

让我们看看如何通过将字符串“ Python”转换为Base64字符串来工作。

字符的ASCII值P, y, t, h, o, n15, 50, 45, 33, 40, 39分别。我们可以用8位二进制表示这些ASCII值,如下所示:

01010000 01111001 01110100 01101000 01101111 01101110

回想一下,Base64字符仅代表6位数据。现在,我们将8位二进制序列重新分组为6位的块。生成的二进制文件将如下所示:

010100 000111 100101 110100 011010 000110 111101 101110

注意:有时我们无法将数据分组为6位序列。如果发生这种情况,我们必须填充序列

使用6位一组的数据,我们可以获得每个组的十进制值。使用最后的结果,我们得到以下十进制值:

20 7 37 52 26 6 61 46

最后,我们将使用Base64转换表将这些小数转换为适当的Base64字符:

如您所见,该值20对应于字母U。然后,我们观察7并观察到它已映射到H。继续对所有十进制值进行此查找,我们可以确定“ Python”表示为UHl0aG9uBase64编码时。您可以使用在线转换器来验证此结果。

为了对字符串进行Base64编码,我们将其转换为二进制序列,然后转换为十进制序列,最后,使用查找表获取一串ASCII字符。在对它如何工作有了更深入的了解之后,让我们看一下为什么我们要对Base64编码数据。

为什么要使用Base64编码?

在计算机中,所有不同类型的数据都以1和0传输。但是,某些通信通道和应用程序无法理解其接收的所有位。这是因为1和0序列的含义取决于它表示的数据类型。例如,10110001如果它代表字母或图像,则必须进行不同的处理。

要解决此限制,您可以将数据编码为文本,以提高正确传输和处理数据的机会。Base64是一种将二进制数据转换为ASCII字符的流行方法,大多数网络和应用程序都广泛理解它。

邮件服务器中经常使用Base64编码的常见现实世界场景。它们最初是为处理文本数据而构建的,但我们也希望它们能够通过消息发送图像和其他媒体。在这些情况下,您的媒体数据在发送时将被Base64编码。然后,它将在收到Base64时对其进行解码,以便应用程序可以使用它。因此,例如,HTML中的图像可能如下所示:

了解数据有时需要以文本形式发送,以便不会损坏,让我们看一下如何使用Python对Base64进行编码和解码。

使用Python编码字符串

Python 3提供了一个base64模块,使我们可以轻松地对信息进行编码和解码。我们首先将字符串转换为类似字节的对象。转换后,我们可以使用base64模块对其进行编码。

在新文件中encoding_text.py,输入以下内容:

import base64

message = "Python is fun"
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')

print(base64_message)

在上面的代码中,我们首先导入了base64模块。该message变量保存我们输入的字符串进行编码。我们使用字符串的encode方法将其转换为类似字节的对象,并将其存储在中message_bytes。然后,我们使用该方法对Base64进行编码message_bytes并存储结果。我们最终通过解码为ASCII 来获得Base64转换的字符串表示形式。base64_bytesbase64.b64encodebase64_bytes

注意:从字符串到字节以及从字节到字符串的转换时,请务必使用与相同的编码格式。这样可以防止数据损坏。

运行此文件将提供以下输出:

$ python3 encoding_text.py
UHl0aG9uIGlzIGZ1bg==

现在让我们看看如何将Base64字符串解码为其原始表示。

使用Python解码字符串

解码Base64字符串本质上是与编码过程相反的过程。我们将Base64字符串解码为未编码数据的字节。然后,我们将类似字节的对象转换为字符串。

在名为的新文件中decoding_text.py,编写以下代码:

import base64

base64_message = 'UHl0aG9uIGlzIGZ1bg=='
base64_bytes = base64_message.encode('ascii')
message_bytes = base64.b64decode(base64_bytes)
message = message_bytes.decode('ascii')

print(message)

再一次,我们需要base64导入模块。然后,我们使用将消息编码为类似字节的对象encode('ASCII')。我们继续通过调用将base64.b64decode解码base64_bytesmessage_bytes变量的方法。最后,我们将其解码message_bytes为一个字符串对象message,从而使其易于阅读。

运行此文件以查看以下输出:

$ python3 decoding_text.py
Python is fun

现在我们可以对字符串数据进行编码和解码了,让我们尝试对二进制数据进行编码。

使用Python编码二进制数据

如前所述,Base64编码主要用于将二进制数据表示为文本。在Python中,我们需要读取二进制文件,然后Base64对其字节进行编码,以便我们生成其编码字符串。

让我们看看如何编码该图像:

创建一个新文件encoding_binary.py并添加以下内容:

import base64

with open('logo.png', 'rb') as binary_file:
    binary_file_data = binary_file.read()
    base64_encoded_data = base64.b64encode(binary_file_data)
    base64_message = base64_encoded_data.decode('utf-8')

    print(base64_message)

让我们看一下上面的代码片段。我们使用打开文件open('my_image.png', 'rb')。注意我们如何传递'rb'参数和文件路径-这告诉Python我们正在读取二进制文件。如果不使用'rb',Python会假定我们正在读取文本文件。

然后,我们使用该read()方法将文件中的所有数据放入binary_file_data变量中。与我们对待字符串的方式类似,我们使用Base64对字节进行编码base64.b64encode,然后使用decode('utf-8')on base64_encoded_data来使用人类可读的字符获取Base64编码的数据。

执行代码将产生类似于以下内容的输出:

$ python3 encoding_binary.py
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1klEQVQ4jY2TTUhUURTHf+fy/HrjhNEX2KRGiyIXg8xgSURuokXLxFW0qDTaSQupkHirthK0qF0WQQQR0UCbwCQyw8KCiDbShEYLJQdmpsk3895p4aSv92ass7pcfv/zP+fcc4U6kXKe2pTY3tjSUHjtnFgB0VqchC/SY8/293S23f+6VEj9KKwCoPDNIJdmr598GOZNJKNWTic7tqb27WwNuuwGvVWrAit84fsmMzE1P1+1TiKMVKvYUjdBvzPZXCwXzyhyWNBgVYkgrIow09VJMznpyebWE+Tdn9cEroBSc1JVPS+6moh5Xyjj65vEgBxafGzWetTh+rr1eE/c/TMYg8hlAOvI6JP4KmwLgJ4qD0TIbliTB+sunjkbeLekKsZ6Zc8V027aBRoBRHVoduDiSypmGFG7CrcBEyDHA0ZNfNphC0D6amYa6ANw3YbWD4Pn3oIc+EdL36V3od0A+MaMAXmA8x2Zyn+IQeQeBDfRcUw3B+2PxwZ/EdtTDpCPQLMh9TKx0k3pXipEVlknsf5KoNzGyOe1sz8nvYtTQT6yyvTjIaxsmHGB9pFx4n3jIEfDePQvCIrnn0J4B/gA5J4XcRfu4JZuRAw3C51OtOjM3l2bMb8Br5eXCsT/w/EAAAAASUVORK5CYII=

您的输出可能会有所不同,具体取决于您选择编码的图像。

现在我们知道了如何在Python中对Bas64编码二进制数据,让我们继续对Base64解码二进制数据进行操作。

使用Python解码二进制数据

Base64解码二进制文件类似于Base64解码文本数据。关键区别在于,在Base64解码字符串之后,我们将数据另存为二进制文件而不是字符串。

让我们看看如何通过创建一个名为的新文件在实践中对Base64解码二进制数据decoding_binary.py。在Python文件中输入以下代码:

import base64

base64_img = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAA' \
            'LEwEAmpwYAAAB1klEQVQ4jY2TTUhUURTHf+fy/HrjhNEX2KRGiyIXg8xgSURuokX' \
            'LxFW0qDTaSQupkHirthK0qF0WQQQR0UCbwCQyw8KCiDbShEYLJQdmpsk3895p4aS' \
            'v92ass7pcfv/zP+fcc4U6kXKe2pTY3tjSUHjtnFgB0VqchC/SY8/293S23f+6VEj' \
            '9KKwCoPDNIJdmr598GOZNJKNWTic7tqb27WwNuuwGvVWrAit84fsmMzE1P1+1TiK' \
            'MVKvYUjdBvzPZXCwXzyhyWNBgVYkgrIow09VJMznpyebWE+Tdn9cEroBSc1JVPS+' \
            '6moh5Xyjj65vEgBxafGzWetTh+rr1eE/c/TMYg8hlAOvI6JP4KmwLgJ4qD0TIbli' \
            'TB+sunjkbeLekKsZ6Zc8V027aBRoBRHVoduDiSypmGFG7CrcBEyDHA0ZNfNphC0D' \
            '6amYa6ANw3YbWD4Pn3oIc+EdL36V3od0A+MaMAXmA8x2Zyn+IQeQeBDfRcUw3B+2' \
            'PxwZ/EdtTDpCPQLMh9TKx0k3pXipEVlknsf5KoNzGyOe1sz8nvYtTQT6yyvTjIax' \
            'smHGB9pFx4n3jIEfDePQvCIrnn0J4B/gA5J4XcRfu4JZuRAw3C51OtOjM3l2bMb8' \
            'Br5eXCsT/w/EAAAAASUVORK5CYII='

base64_img_bytes = base64_img.encode('utf-8')
with open('decoded_image.png', 'wb') as file_to_save:
    decoded_image_data = base64.decodebytes(base64_img_bytes)
    file_to_save.write(decoded_image_data)

在上面的代码中,我们首先将Base64字符串数据转换为可以解码的类似字节的对象。当base64解码二进制文件时,您必须知道要解码的数据类型。例如,此数据仅对PNG文件有效,而对MP3文件无效,因为它对图像进行编码。

打开目标文件后,我们将使用Base64解码数据base64.decodebytes,该方法base64.b64decode与字符串使用的方法不同。此方法应用于解码二进制数据。最后,我们将解码后的数据写入文件。

在执行的目录中decoding_binary.py,您现在将看到一个新decoded_image.png文件,其中包含先前编码的原始图像。

结论

Base64编码是一种流行的技术,可以将不同二进制格式的数据转换为ASCII字符字符串。当将数据传输到无法处理原始二进制数据但可以轻松处理文本的网络或应用程序时,此功能很有用。

使用Python,我们可以使用该base64模块对Base64编码和解码文本和二进制数据。