• 使用Python进行Base64编码和解码


    假设您有一个想要通过网络传输的二进制图像文件。您很惊讶对方没有正确接收该文件 - 该文件只是包含奇怪的字符!

    嗯,您似乎试图以原始位和字节格式发送文件,而所使用的媒体是为流文本而设计的。

    避免此类问题的解决方法是什么?答案是Base64编码。在本文中,我将向您展示如何使用 Python 对二进制图像进行编码和解码。该程序被说明为一个独立的本地程序,但您可以将该概念应用于不同的应用程序,例如将编码图像从移动设备发送到服务器以及许多其他应用程序。

    什么是 Base64?

    在深入了解本文之前,让我们先定义一下 Base64 的含义。

    Base64 是一种将 8 位二进制数据编码为可以用 6 位表示的格式的方法。仅使用字符 A-Za-z0-9+、 / 用来表示数据,其中 = 用于填充数据。例如,使用此编码,三个 8 位字节将转换为四个 6 位组。

    术语 Base64 取自多用途互联网邮件扩展 (MIME) 标准,该标准广泛用于 HTTP 和 XML,最初是为编码电子邮件附件以进行传输而开发的。

    我们为什么使用 Base64?

    Base64 对于二进制数据表示非常重要,因此它允许二进制数据以看起来和充当纯文本的方式表示,这使得存储在数据库中、在电子邮件中发送或在其他应用程序中使用更加可靠。基于文本的格式,例如 XML。 Base64 主要用于以 ASCII 字符串格式表示数据。

    正如本文介绍中提到的,如果没有 Base64,有时数据将根本无法读取。

    Base64 编码

    Base64 编码是将二进制数据转换为 64 个字符的有限字符集的过程。如第一节所示,这些字符是 A-Za-z0-9 + 和 / (数一数,你注意到它们加起来是 64 了吗?)。该字符集被认为是最常见的字符集,被称为 MIME 的 Base64。它使用 A-Za-z 和 0-9 作为前 62 个值,以及 和 / 用于最后两个值。

    Base64编码的数据最终会比原始数据更长,因此如上所述,每3个字节的二进制数据,至少有4个字节的Base64编码数据。这是因为我们将数据压缩成更小的字符集。

    您是否见过如下所示的原始电子邮件文件的一部分(很可能源自未发送的电子邮件)?如果是这样,那么您已经看到了 Base64 编码的实际应用! (如果你注意到最后有 = ,你可以断定这是 Base64 编码,因为编码过程中使用了等号进行填充。)

    1. Content-Type: text/plain; charset=UTF-8
    2. Content-Transfer-Encoding: base64
    3. 2KfZhNiz2YTYp9mFINi52YTZitmD2YUg2YjYsdit2YXYqSDYp9mE2YTZhyDZiNio2LHZg9in2KrZ
    4. h9iMDQoNCtij2YjYryDZgdmC2Lcg2KfZhNin2LPYqtmB2LPYp9ixINi52YYg2KfZhNmF2YLYsdix
    5. 2KfYqiDYp9mE2K/Ysdin2LPZitipINin2YTYqtmKINiq2YbYtdit2YjZhiDYqNmH2Kcg2YTZhdmG
    6. INmK2LHZitivINin2YTYqtmI2LPYuSDZgdmKDQrYt9mE2Kgg2KfZhNi52YTZhSDYp9mE2LTYsdi5
    7. 2YrYjCDYudmE2YXYpyDYqNij2YbZiiDYutmK2LEg2YXYqtiu2LXYtSDYqNin2YTYudmE2YUg2KfZ
    8. hNi02LHYudmKINmI2KPZgdiq2YLYryDZhNmE2YXZhtmH2Kwg2KfZhNi52YTZhdmKDQrZhNiw2YTZ
    9. gy4NCg0K2KzYstin2YPZhSDYp9mE2YTZhyDYrtmK2LHYpyDYudmE2Ykg2YbYtdit2YPZhSDZgdmK
    10. INmH2LDYpyDYp9mE2LTYo9mGLg0KDQrYudio2K/Yp9mE2LHYrdmF2YYNCg==
    11. --089e0141aa264e929a0514593016
    12. Content-Type: text/html; charset=UTF-8
    13. Content-Transfer-Encoding: base64

    Base64分多步进行,如下:

    • 要编码的文本转换为其各自的十进制值,即转换为相应的 ASCII 值(即 a:97、b:98 等)。这是 ASCII 表。
    • 将上述步骤中获得的十进制值转换为其等价的二进制值(即 97: 01100001)。
    • 将所有二进制等价物连接起来,获得一大组二进制数。
    • 一大堆二进制数被分成相等的部分,每个部分仅包含 6 位。
    • 相等的 6 位组将转换为其十进制等效值。
    • 最后,十进制等值转换为其 Base64 值(即 4: E)。以下是十进制值及其 Base64 字母表。

    Base64解码

    Base64 解码与 Base64 编码相反。换句话说,它是通过与上一节中描述的步骤相反的步骤来执行的。

    所以Base64解码的步骤可以描述如下:

    • 字符串中的每个字符都会更改为其 Base64 十进制值。
    • 获得的十进制值将转换为其等价的二进制值。
    • 从获得的每个二进制数中截断二进制数的前两位,并将这组 6 位组合在一起,形成一大串二进制数字。
    • 将上一步获得的大串二进制数字分成 8 位一组。
    • 8 位二进制数将转换为其等值的十进制数。
    • 最后,将获得的十进制值转换为相应的 ASCII 值。

    字符串的Base64编码和解码

    一旦您了解了幕后发生的事情,您就会更容易理解这一切是如何运作的。让我们尝试编码和解码一个简单的三字母单词,Hey

    我们首先将单词的每个字母转换为其等效的 ASCII,然后将等效的 ASCII 转换为二进制。这为我们提供了以下值:

    ASCII 索引值8 位二进制值
    H7201001000
    e10101100101
    y12101111001

    换句话说,我们可以像这样以二进制形式编写 Hey

    01001000 01100101 01111001

    总共 24 位,当转换为 6 位组时,每个位产生四个值:

    010010 000110 010101 111001

    在 Base64 表中,字符 A 到 Z 由值 0 到 25 表示。字符 a 到 z 由值 26 到 51 表示。数字 0 到 9 由值 52 到 61 表示。字符 + 和 / 用 62 和 63 表示。字符 = 用于在无法将位正确分为 6 组时进行填充。

    我们现在将重新排列的位转换为数值,然后获取代表这些数值的字符。

    6 位二进制值Base64 索引值
    01001018
    0001106G
    01010121V
    111001575

    根据我们上面的计算,字母 Hey 在 Base64 编码时将变成 SGV5。我们可以使用以下代码测试这是否正确:        

    1. from base64 import b64encode
    2. text_binary = b'Hey'
    3. # SGV5
    4. print(b64encode(text_binary))

    整个过程反向完成,在Base64解码后得到我们的原始数据。

    现在,我将快速向您展示另一个单词 Heyo 的编码,以解释编码字符串中 = 的出现。

    ASCII 索引值8 位二进制值
    H7201001000
    e10101100101
    y12101111001
    o11101101111

    一共有32位。这将为我们提供五个不同的 6 位组,其中有两个剩余位:11。我们用 0000 填充它们以获得 6 位组。根据上述排列将 6 位组成一组将得到以下结果:

    010010 000110 010101 111001 011011 110000

    重新排列的位将根据 Base64 索引值返回以下字符。

    6 位二进制值Base64 索引值
    01001018
    0001106G
    01010121V
    111001575
    01101127b
    11000048w

    这意味着 Heyo 的 Base64 编码值为 SGV5bw==。每个 = 代表一对 00,我们添加它们用于填充原始位序列。

    1. from base64 import b64encode
    2. text_binary = b'Heyo'
    3. # SGV5bw==
    4. print(b64encode(text_binary))

    对图像进行 Base64 编码

    现在让我们开始讨论本文的重点。在本节中,我将向您展示如何使用 Python 轻松地对图像进行 Base64 编码。

    我将使用以下二进制图像。继续下载它,让我们开始使用 Python! (我假设图像的名称是 deer.gif。)

    使用Python进行Base64编码和解码

    为了在Python中使用Base64,我们要做的第一件事就是导入base64模块:

    导入base64

    为了对图像进行编码,我们只需使用函数 base64.b64encode(s) 即可。 Python对该函数的描述如下:

    使用 Base64 对类似字节的对象 s 进行编码并返回编码后的字节。

    因此,我们可以执行以下操作来对图像进行 Base64 编码:

    1. import base64
    2. image = open('deer.gif', 'rb') #open binary file in read mode
    3. image_read = image.read()
    4. image_64_encode = base64.b64encode(image_read)

    如果您想查看编码过程的输出,请键入以下内容:

    打印 image_64_encode

    Base64 解码图像

    要使用 Python 解码图像,我们只需使用 base64.b64decode(s) 函数。 Python 提及了有关此函数的以下内容:

    解码 Base64 编码的类似字节的对象或 ASCII 字符串并返回解码后的字节。

    因此,为了解码我们在上一节中编码的图像,我们执行以下操作:

    base64.decode(image_64_encode)

    把它们放在一起

    让我们将用于 Base64 编码和解码图像的程序放在一起。执行此操作的 Python 脚本应如下所示:

    1. import base64
    2. image = open('deer.gif', 'rb')
    3. image_read = image.read()
    4. image_64_encode = base64.b64encode(image_read)
    5. image_64_decode = base64.b64decode(image_64_encode)
    6. image_result = open('deer_decode.gif', 'wb') # create a writable image and write the decoding result
    7. image_result.write(image_64_decode)

    如果您打开桌面上的 deer_decode.gif,您会发现您拥有我们在第一步中编码的原始图像 deer.gif

    正如我们从本文中看到的,Python 使执行看似复杂的任务变得非常容易。

    URL 安全编码和解码

    正如我在本教程前面提到的,除了常规字母数字值之外,Base64 编码还使用字符 + 和 / 。但是,这些字符在 URL 中具有特殊含义。这意味着使用这些字符的 Base64 编码值如果在 URL 内部使用,可能会导致意外行为。

    此问题的一种解决方案是使用 urlsafe_base64encode() 和 urlsafe_base64decode() 函数对任何数据进行编码和解码。这些函数在编码过程中将 + 替换为 -,将 / 替换为 _

    下面是一个 Python 示例,显示了这种差异:

    1. import base64
    2. image = open('dot.jpg', 'rb')
    3. image_data = image.read()
    4. unsafe_encode = base64.b64encode(image_data)
    5. safe_encode = base64.urlsafe_b64encode(image_data)
    6. # b'/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNr....
    7. print(unsafe_encode)
    8. # b'_9j_4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP_sABFEdWNr....
    9. print(safe_encode)

    学习Python

    无论您是刚刚入门还是希望学习新技能的经验丰富的程序员,都可以通过我们完整的 Python 教程指南学习 Python。

    这篇文章已根据 Nitish Kumar 的贡献进行了更新。 Nitish 是一名 Web 开发人员,拥有在各种平台上创建电子商务网站的经验。他将业余时间花在个人项目上,让他的日常生活变得更轻松,或者在晚上与朋友一起散步。

  • 相关阅读:
    51单片机自学报告--实验部分
    POI Excel单元格样式超过最大数(4000或64000)的解决方案
    【C++】认识类和对象
    创建SpringBoot工程
    【OCR】合同上批量贴印章
    IP-guard WebServer 权限绕过漏洞复现(QVD-2024-14103)
    Allegro PCB编辑界面功能全面介绍图文教程
    1.3以 numpy 为例认识三方库及其使用_python量化实用版教程(初级)
    无序数组计算排序后最大相邻差
    SpringBoot--启动时的事件机制
  • 原文地址:https://blog.csdn.net/lmrylll/article/details/132638849