Base32编码和解码问题 | 豆包MarsCode AI刷题

185 阅读3分钟

题目链接:Base32 编码和解码问题 - MarsCode

题目描述

实现 Base32 的编码和解码函数。Base32 编码以 5 位为一组,将二进制数据映射到字符表,用于将二进制数据表示为字符串。输入数据若不足 5 的倍数位则需补零,编码后按长度需求在末尾补 + 符号。解码时去除 + 符号,解析还原出原始数据。

问题分析

  1. 编码流程
    • 将字符串转换为二进制。
    • 若长度不满 5 的倍数则补零。
    • 将二进制串以 5 位为一组转换为索引,映射到对应字符。
    • 根据原始字符串长度在末尾补 +
  2. 解码流程
    • 将字符串拆成可以解码的子串, 比如"bljhy+++b0zj5+++"先拆成"bljhy+++","b0zj5+++"。
    • 对于每个子串:
      • 统计 + 的数量,得到原始数据末尾有几个0。
      • 将每个字符映射到对应索引,索引转换为二进制形式并补全。
      • 去除末尾的0,每8位还原成ASCII字符。

解题思路

  1. 主函数 solution

    • 调用 encodedecode 函数。
    • 对编码字符串调用 encode;对解码字符串进行拆分,分别调用 decode然后拼接。
    • 结果格式为编码和解码结果的拼接输出。
  2. 编码函数 encode

    • 使用 convert_string_to_binary 将输入字符串转为二进制字符串。
    • 若不为 5 的倍数则用 completeChar 补零。
    • 每 5 位分组,通过 get_char_by_index 查找字符映射。
    • 对生成字符串补 +
  3. 解码函数 decode

    • 统计 + 数量,并将字符转为 5 位二进制索引。
    • 根据 + 数量确定尾部需去掉的多余零,得到原始数据。
    • 将二进制数据按 8 位分组,并转换为 ASCII 字符,拼接成结果。
  4. 辅助函数

    • completeChar 用于将字符串长度补齐为指定的倍数。
    • convert_string_to_binary 将字符串逐字符转换成二进制串。
    • get_char_by_indexget_index_by_char 分别实现字符和索引间的查找。

代码实现

def solution(rawStr, encodedStr):
    encodeStr = encode(rawStr)
    decodeStr = ""
    start = 0
    for i in range(len(encodedStr)):
        if (encodedStr[i] == '+' and i+1 >= len(encodedStr) or (encodedStr[i] == '+' and encodedStr[i+1] != '+')):
            subStr = encodedStr[start:i + 1]
            start = i + 1
            decodeStr += decode(subStr)
    return encodeStr + ":" + decodeStr

def encode(str):
    bStr = convert_string_to_binary(str)
    bStr = completeChar(bStr, 5, '0')
    result = ""
    for i in range(0, len(bStr), 5):
        subStr = bStr[i:i+5]
        index = int(subStr, 2)
        result += get_char_by_index(index)
    result = completeChar(result, 8, '+')
    return result

def decode(eStr):
    bStr = ""
    plusNum = 0
    plus_rest = {0: 0, 6: 8, 4: 16, 3: 24, 1: 32}
    for c in eStr:
        if c == '+':
            plusNum += 1
            continue
        index = get_index_by_char(c)
        decimal = bin(index)[2:].zfill(5)
        bStr += str(decimal)
    rest = plus_rest[plusNum]
    zeroNum = (len(bStr) % 40) - rest
    bStr = bStr[:-zeroNum]
    result = ""
    for i in range(0, len(bStr), 8):
        subStr = bStr[i:i+8]
        code = int(subStr, 2)
        result += chr(code)
    return result
def completeChar(str,num,char):
    rest = len(str) % num
    if(rest != 0):
        str = str + char*(num-rest)
    return str

def convert_string_to_binary(s):
    binary_str = ""
    for char in s:
        ascii_code = ord(char)
        binary_code = bin(ascii_code)[2:].zfill(8)
        binary_str += binary_code
    return binary_str

index_char_mapping = {
    0: '9',
    1: '8',
    2: '7',
    3: '6',
    4: '5',
    5: '4',
    6: '3',
    7: '2',
    8: '1',
    9: '0',
    10:'m',
    11: 'n',
    12: 'b',
    13: 'v',
    14: 'c',
    15: 'x',
    16: 'z',
    17: 'a',
    18:'s',
    19: 'd',
    20: 'f',
    21: 'g',
    22: 'h',
    23: 'j',
    24: 'k',
    25: 'l',
    26: 'p',
    27: 'o',
    28: 'i',
    29: 'u',
    30: 'y',
    31: 't'
}

# 通过索引查字符
def get_char_by_index(index):
    return index_char_mapping[index]

# 通过字符查索引
def get_index_by_char(char):
    for key, value in index_char_mapping.items():
        if value == char:
            return key
    return -1  # 表示未找到

复杂度分析

  • 时间复杂度:编码和解码都需遍历字符串,为 (O(n))。
  • 空间复杂度:二进制数据存储所需空间为 (O(n))。

总结与收获

该题考察了对字符串二进制编码的实现及位操作技巧,通过处理字符串补零、按位分组和查找索引的方式,加深了对字符编码规则的理解。