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

Encoding and Decoding Base64 Strings in Python

介绍

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

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

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

  • 什么是Base64编码?

  • Base64编码如何工作?

  • 为什么要使用Base64编码?

  • 使用Python编码字符串

  • 使用Python解码字符串

  • 使用Python编码二进制数据

  • 使用Python解码二进制数据

  • 结论

  • 什么是Base64编码?

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

    Base64字符集包含:

  • 26个大写字母

  • 26个小写字母

  • 10个数字

  • +/用于换行(某些实现可能使用不同的字符)

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

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

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

    Base64编码如何工作?

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

  • 取字符串中每个字符的ASCII值

  • 计算ASCII值的8位二进制等效项

  • 只需重新组合数字,即可将8位块转换为6位块

  • 将6位二进制组转换为其各自的十进制值。

  • 使用base64编码表,为每个十进制值分配相应的base64字符。

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

    字符P, y, t, h, o, n的ASCII值分别为15, 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字符:

    Base64 Encoding Table

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

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

    为什么要使用Base64编码?

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

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

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

    1
    <img src="data:image/png;base64,aVRBOw0AKg1mL9...">

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

    使用Python编码字符串

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    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,并使用base64.b64encode方法将结果存储在base64_bytes中。 通过将base64_bytes解码为ASCII,我们最终获得了Base64转换的字符串表示形式。

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

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

    1
    2
    $ python3 encoding_text.py
    UHl0aG9uIGlzIGZ1bg==

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

    使用Python解码字符串

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    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_bytes解码为我们的message_bytes变量。 最后,我们将message_bytes解码为字符串对象message,因此它变得易于阅读。

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

    1
    2
    $ python3 decoding_text.py
    Python is fun

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

    使用Python编码二进制数据

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

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

    Python logo

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

    1
    2
    3
    4
    5
    6
    7
    8
    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编码字节,然后在base64_encoded_data上使用decode('utf-8')来使用人类可读的字符来获取Base64编码的数据。

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

    1
    2
    $ 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解码字符串之后,我们将数据另存为二进制文件而不是字符串。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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.decodebytes对数据进行Base64解码,这是与base64.b64decode不同的用于字符串的方法。 此方法应用于解码二进制数据。 最后,我们将解码后的数据写入文件。

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

    结论

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

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

    您将使用什么应用程序对Base64数据进行编码和解码-