自学内容网 自学内容网

Base64编解码

Base64 主要有以下作用:

一、作用

  1. 数据传输

    • 在网络通信中,Base64 可以将二进制数据编码为 ASCII 字符,使得数据可以在只支持文本传输的通道中进行传输,比如在电子邮件中传输图片、在 HTTP 请求中传输二进制数据等。
    • 避免了一些字符集不兼容的问题,确保数据能够在不同系统和平台之间可靠地传输。
  2. 数据存储

    • 在某些情况下,将二进制数据编码为 Base64 可以更方便地存储在文本文件或数据库中,而不需要专门的二进制存储机制。
  3. URL 和文件名安全

    • Base64 编码后的字符串不包含特殊字符,因此可以安全地用于 URL 参数或文件名,不会引起解析错误。

二、关于数据大小变化

Base64 编码通常会使数据大小增加约 33%。这是因为 Base64 使用 64 个可打印的 ASCII 字符来表示二进制数据,每个 6 位的 Base64 编码单元对应 8 位的原始二进制数据。具体计算如下:

  • 8 位二进制数据可以表示 2 8 = 256 2^8 = 256 28=256 个不同的值。
  • 6 位 Base64 编码可以表示 2 6 = 64 2^6 = 64 26=64 个不同的值。
  • 所以,每 3 个字节(24 位)的原始数据会被编码为 4 个 Base64 字符(24 位),即编码后的数据长度是原始数据长度的 4 / 3 4/3 4/3 倍,增加了约 1 / 3 1/3 1/3,也就是 33%。

需要注意的是,虽然 Base64 编码会增加数据大小,但在某些特定场景下,为了满足数据传输或存储的要求,这种增加是可以接受的。同时,不同类型的数据在经过 Base64 编码后的大小变化可能会有所不同,但大致都在这个比例左右。


一、Base64 的 64 个字符

Base64 使用的 64 个字符包括大写字母 A-Z、小写字母 a-z、数字 0-9 以及两个特殊字符“+”和“/”。具体如下:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

二、编码规则

  1. 首先将需要编码的二进制数据按每 6 个比特为一组进行分组。如果最后一组不足 6 个比特,则在末尾用 0 补齐,使其成为 6 的倍数。
  2. 对于每一组 6 个比特,根据其值在上述 64 个字符中找到对应的字符进行编码。
  3. 如果原始数据的长度不是 3 的倍数,那么在编码后的结果末尾可能会有“=”作为填充字符。具体填充规则如下:
    • 如果原始数据长度除以 3 的余数是 1,则在编码结果末尾添加两个“=”。
    • 如果余数是 2,则在编码结果末尾添加一个“=”。

例如,对于字符串“Man”进行 Base64 编码:

  1. 首先将“Man”转换为 ASCII 码值对应的二进制表示:
    • M 的 ASCII 码值为 77,二进制为 01001101。
    • a 的 ASCII 码值为 97,二进制为 01100001。
    • n 的 ASCII 码值为 110,二进制为 01101110。
  2. 将这三个字符的二进制拼接起来得到:01001101 01100001 01101110。
  3. 按每 6 个比特一组进行分组:010011、010110、000101、101110。
  4. 分别将每组转换为十进制值:19、22、5、46。
  5. 对照 Base64 的 64 个字符表,找到对应的字符:T、W、F、u。
  6. 所以“Man”的 Base64 编码结果为“TWFu”。

三、Base64 解码规则

  1. 首先,识别出 Base64 编码的字符串中的有效字符(即大写字母 A-Z、小写字母 a-z、数字 0-9、“+”和“/”)。
  2. 将每个有效字符转换为对应的 6 位二进制值。例如,“A”对应 000000,“B”对应 000001,以此类推。
  3. 将这些 6 位二进制值按顺序拼接起来,每 8 位一组,转换为对应的 ASCII 码值,从而得到原始的二进制数据。
  4. 如果编码字符串末尾有“=”填充字符,则在解码时忽略这些填充字符,并根据填充字符的数量确定需要丢弃的二进制位。如果末尾有一个“=”,则丢弃最后 4 个二进制位;如果末尾有两个“=”,则丢弃最后 8 个二进制位。

四、举例说明

以 Base64 编码字符串“TWFu”为例进行解码:

  1. 首先确定每个字符对应的 6 位二进制值:
    • “T”对应 010100。
    • “W”对应 010111。
    • “F”对应 000111。
    • “u”对应 011101。
  2. 将这些二进制值拼接起来得到:010100010111000111011101。
  3. 按每 8 位一组进行划分:01001101、01100001、01101110。
  4. 将这些 8 位二进制值转换为 ASCII 码值,得到:77(M)、97(a)、110(n)。

所以,“TWFu”解码后得到的原始数据为“Man”。

将二进制数据编码为 ASCII 字符主要有以下几个原因:

一、兼容性和通用性

  1. ASCII 字符集是一种广泛被接受和理解的字符编码标准。许多系统、软件和通信协议都能很好地处理 ASCII 字符。通过将二进制数据编码为 ASCII 字符,可以确保数据在不同的环境和平台中具有更好的兼容性和通用性。
  2. 例如,在电子邮件系统中,只允许传输 ASCII 字符。如果要发送二进制数据(如图片、音频文件等),就需要将其编码为 ASCII 字符,以便能够在电子邮件中顺利传输。

二、文本传输通道的限制

  1. 在一些通信场景中,只支持文本传输。比如 HTTP 请求通常是基于文本的,如果要在 HTTP 请求中传输二进制数据,就需要将其编码为 ASCII 字符,以便能够在 HTTP 协议中正确传输。
  2. 网络中的很多中间设备(如防火墙、代理服务器等)可能对非 ASCII 字符的二进制数据进行过滤或限制。将二进制数据编码为 ASCII 字符可以避免这些问题,确保数据能够顺利通过各种网络设备。

三、可读性和可调试性

  1. ASCII 字符是人类可读的,这使得编码后的数据在一定程度上具有可读性。在调试和排查问题时,可以更容易地理解和分析编码后的数据。
  2. 例如,如果在网络传输中出现问题,可以通过查看编码后的 ASCII 字符来初步判断数据是否完整或是否存在错误,而不需要直接处理难以理解的二进制数据。

不编码为 ASCII 字符在某些特定情况下也是可以的,但会面临很多问题:

  1. 如果不编码为 ASCII 字符,数据可能无法在只支持文本传输的通道中传输,导致通信失败。
  2. 不同系统和平台对非 ASCII 字符的二进制数据的处理方式可能不同,可能会导致兼容性问题。
  3. 在一些场景下,非 ASCII 字符的二进制数据可能会被错误地解释或截断,影响数据的完整性。

综上所述,将二进制数据编码为 ASCII 字符在很多情况下是必要的,可以提高数据的兼容性、通用性和可传输性。


当原始数据长度不是 3 的整数倍时,Base64 编码和解码过程如下:

一、编码过程

假设原始数据为“Ma”,只有两个字符。

  1. 首先将“Ma”转换为 ASCII 码值对应的二进制表示:
    • M 的 ASCII 码值为 77,二进制为 01001101。
    • a 的 ASCII 码值为 97,二进制为 01100001。
  2. 将这两个字符的二进制拼接起来得到:0100110101100001。
  3. 由于长度不足 3 个字节,在末尾补两个 0,变为:010011010110000100。
  4. 按每 6 个比特一组进行分组:010011、010110、000100。
  5. 前三个组分别转换为十进制值:19、22、4。
  6. 对照 Base64 的 64 个字符表,找到对应的字符:T、W、E。
  7. 由于最后一组不足 6 个比特,且原始数据长度除以 3 的余数是 2,所以在编码结果末尾添加一个“=”,最终编码结果为“TWE=”。

二、解码过程

对于编码结果为“TWE=”的字符串进行解码。

  1. 首先识别出有效字符“T”“W”“E”,忽略末尾的“=”。
  2. 将每个有效字符转换为对应的 6 位二进制值:
    • “T”对应 010100。
    • “W”对应 010111。
    • “E”对应 000100。
  3. 将这些二进制值拼接起来得到:010100010111000100。
  4. 由于末尾有一个“=”,说明原始数据长度除以 3 的余数是 2,所以丢弃最后 4 个二进制位,得到:0100110101100001。
  5. 将这个 16 位二进制值按每 8 位一组进行划分:01001101、01100001。
  6. 将这些 8 位二进制值转换为 ASCII 码值,得到:77(M)、97(a)。

所以,“TWE=”解码后得到的原始数据为“Ma”。


原文地址:https://blog.csdn.net/u013318019/article/details/142766987

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!