算法~base64算法理解

base64

Base64 是一种用于将二进制数据编码成 ASCII 字符的编码方式。它主要用于在文字环境中传输或存储二进制数据,如在电子邮件、XML 文件、URL 参数等。Base64 编码不是一种加密算法,而是一种编码方式,其主要作用是将二进制数据转换为文本数据,以便更容易在文本协议中处理。

Base64 编码使用 64 个不同的字符来表示二进制数据。这些字符包括大小写字母 A-Z 和 a-z、数字 0-9,以及两个额外的字符通常是 "+" 和 "/"。有时候,为了适应不同的环境,可能还会使用额外的字符,如 "=" 用于填充。

编码的过程如下:

  1. 将待编码的数据划分为 3 个字节的块。
  2. 将每个字节块转换为一个 24 位的二进制数。
  3. 将这个 24 位的二进制数分为四个 6 位的块。
  4. 将每个 6 位的块转换为对应的 Base64 字符。
  5. 如果原始数据的长度不是3的倍数,可能会有一些填充字符(通常是 "=")。

解码的过程是编码的逆过程,将 Base64 字符转换回原始的二进制数据。

Base64 的主要优点是它能够将二进制数据以文本形式呈现,且编码后的数据长度通常比原始数据小,这对于在文本协议中传输二进制数据是很有用的。然而,它并不是为了安全而设计的,因此不应用于对数据进行加密。

url base64

UrlBase64 是 Base64 编码的一种变体,主要用于在 URL 中安全地传输二进制数据。它与标准的 Base64 编码相比,有一些微小的差异,以确保编码后的字符在 URL 中不会引起问题。

UrlBase64 主要有以下两个特点:

  1. 字符集不同: 在标准的 Base64 编码中,使用字符 "+", "/",而这两个字符在 URL 中有特殊的含义,可能会引起歧义或导致 URL 解析错误。为了解决这个问题,UrlBase64 将字符 "+" 替换为 "-", 将 "/" 替换为 "_"。

  2. 去掉填充字符: 标准的 Base64 编码在最后可能会使用一个或两个 "=" 字符进行填充,以使编码后的字符串长度是4的倍数。但是在 URL 中,这些填充字符可能引起问题,因此 UrlBase64 通常去掉填充字符,直接使用编码后的字符串。

总体而言,UrlBase64 是为了适应 URL 中的特殊需求而修改的 Base64 编码。在处理需要在 URL 中传递的二进制数据时,使用 UrlBase64 可以确保编码后的字符串在 URL 中是安全且可靠的。在使用 UrlBase64 解码时,需要在解码之前将 "_" 替换为 "/",将 "-" 替换为 "+",并根据需要添加填充字符。

算法演变

计算字符串在转成 Base64 编码后的长度可以通过以下简单的公式来估算:

  1. 计算原始字符串的字节数(每个字符通常占用一个字节,但是对于 Unicode 字符,可能会占用多个字节)。

  2. 计算 Base64 编码后的长度:

    这个公式的解释如下:

    • 每个 Base64 字符表示 6 个比特(2^6 = 64)。
    • 每组 3 个字节的数据被编码成 4 个 Base64 字符。
    • 如果原始字节数不能被 3 整除,可能会有填充字符 "="。

以下是一个简单的 Python 示例,演示如何计算字符串经过 Base64 编码后的长度:

  • 使用上面公式计算长度

base64最小长度是4位,每个base64的长度都是4的倍数,不够长度结尾补=符号
公式计算base64实际的长度,整除向上取整,例如18/6=2,28/6=3,38/6=4,48/6=6。

原字符 每6bit一组 base64编码
a 1*8/6=2 YQ==
ab 2*8/6=3 YWI=
abc 3*8/6=4 YWJj
abcd 4*8/6=6 YWJjZA==
abcde 5*8/6=7[] YWJjZGU=

pyhon实现

import base64

def base64_encoded_length(input_string):
    # 计算原始字节数
    original_bytes = len(input_string.encode('utf-8'))
    
    # 计算 Base64 编码后的长度
    base64_length = (original_bytes * 8 + 5) // 6
    
    # 考虑填充字符
    if original_bytes % 3 != 0:
        base64_length += 4 - (original_bytes % 3) * 2
    
    return base64_length

# 示例
original_string = "Hello, World!"
length_before = len(original_string)
length_after = base64_encoded_length(original_string)

print(f"原始字符串长度:{length_before}")
print(f"Base64 编码后长度:{length_after}")

请注意,这只是一个估算。实际的编码长度可能会受到编码实现细节的影响,例如是否包含换行符等。