base32编码解码|豆包MarsCode AI 刷题

154 阅读3分钟

要实现 Base32 编码和解码函数,首先我们需要了解 Base32 的编码规则和如何在编码和解码时处理数据。下面是如何进行 Base32 编码和解码的步骤。

Base32 编码步骤

  1. 预处理原始数据:如果原始数据的 bit 数量不是 5 的倍数,则在末尾补充必要的 0,直到数据的 bit 数量是 5 的倍数。

  2. 分组:将二进制数据按照 5 bit 一组进行分割。

  3. 索引映射:对于每一组 5 bit 数据,计算其对应的索引(0 到 31),并使用索引表将这些索引转换为字符。

  4. 填充:根据原始数据的长度,决定需要在末尾添加多少个 + 符号。填充规则如下:

    • 如果原始数据的 bit 长度除以 40 的余数是 0,则不需要填充。
    • 如果余数是 8,则填充 6 个 +
    • 如果余数是 16,则填充 4 个 +
    • 如果余数是 24,则填充 3 个 +
    • 如果余数是 32,则填充 1 个 +

Base32 解码步骤

  1. 去掉填充:首先去掉末尾的 + 符号。
  2. 索引反转:根据字符表中的索引,将 Base32 字符串转换为相应的二进制数据。
  3. 合并:将解码后的二进制数据合并回原始数据,并去掉末尾的填充的零。

Base32 的字符表

根据题目给出的字符表:

plaintext
复制代码
索引:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
字符:9 8 7 6 5 4 3 2 1 0 m n b v c x z a s d f g h j k l p o i u y t

Python 代码实现

python
复制代码
# Base32字符表
base32_chars = ['9', '8', '7', '6', '5', '4', '3', '2', '1', '0', 'm', 'n', 'b', 'v', 'c', 'x', 'z', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'p', 'o', 'i', 'u', 'y', 't']

# Base32编码函数
def base32_encode(raw_str):
    # 将字符串转为二进制
    raw_bin = ''.join(f'{ord(c):08b}' for c in raw_str)
    
    # 补齐二进制字符串至 5 的倍数
    remainder = len(raw_bin) % 5
    if remainder != 0:
        raw_bin = raw_bin + '0' * (5 - remainder)
    
    # 分成 5 bit 一组
    chunks = [raw_bin[i:i+5] for i in range(0, len(raw_bin), 5)]
    
    # 对每个 5 bit 组进行编码
    encoded_str = ''.join(base32_chars[int(chunk, 2)] for chunk in chunks)
    
    # 填充 `+` 的规则
    mod = len(raw_bin) % 40
    if mod == 8:
        encoded_str += '++++++'
    elif mod == 16:
        encoded_str += '++++'
    elif mod == 24:
        encoded_str += '+++'
    elif mod == 32:
        encoded_str += '+'
    
    return encoded_str

# Base32解码函数
def base32_decode(encoded_str):
    # 去掉末尾的 `+` 填充
    padding = encoded_str.count('+')
    encoded_str = encoded_str.rstrip('+')
    
    # 将 Base32 字符转为对应的二进制
    bin_str = ''.join(f'{base32_chars.index(c):05b}' for c in encoded_str)
    
    # 去掉末尾的补齐零
    decoded_bin = bin_str[:len(bin_str) - padding * 5]
    
    # 将二进制转为字符
    decoded_str = ''.join(chr(int(decoded_bin[i:i+8], 2)) for i in range(0, len(decoded_bin), 8))
    
    return decoded_str

# 测试示例
raw_str = "foo"
encoded_str = base32_encode(raw_str)
print(f"Encoded: {encoded_str}")  # b0zj5+++

decoded_str = base32_decode("b0zj5+++")
print(f"Decoded: {decoded_str}")  # foo

说明

  1. Base32编码:将输入的字符串 raw_str 转为二进制,补齐至 5 的倍数,分割成 5 bit 的组,然后用 Base32 字符表查找索引,将其转换为字符,最后根据剩余的位数加上必要的 + 填充。
  2. Base32解码:首先去掉 + 填充,按 Base32 字符表查找字符的索引,转换为二进制数据,去除填充的零,最终恢复为原始的字符串。

测试

python
复制代码
raw_str = "foo"
encoded_str = base32_encode(raw_str)
print(encoded_str)  # 输出: b0zj5+++

decoded_str = base32_decode(encoded_str)
print(decoded_str)  # 输出: foo

这个实现应该可以满足题目的要求,完成 Base32 编码和解码。