题目解析
实现Base32编解码,输入给出两个字符串,一个是需要编码的字符串,一个是需要解码的字符串。输出为两个结果使用":"连接。分别实现两个算法即可。
编码:编码算法的输入是二进制数字,因此需要先将需要编码的字符串转成二进制数据。在python中使用字符串内置的encode()的方法可以获得对应编码系统的二进制数据。题目没有指明,但是本题使用的常见的"utf-8"编码格式,即每个字符在"utf-8"编码系统中寻找对应的编码。 然后按照题目给出的编码算法实现具体编码代码即可。 解码时需要将编码过程反转即可。
背景知识
-
Base32指的是字符集的大小为32。即二进制数据每5位一组,表示字符集中一个字符的索引。同理Base64则二进制数据每6位一组。 为什么要使用Base64或Base32:邮件附件或Web图片编码后可以在只支持文本格式的系统中传输。
-
Unicode字符集:Unicode字符集包含了世界上多数语言的字符,并定义了每个字符到码点(Code Point, 一个唯一的数字代码)之间的映射关系。
-
"UTF-8"编码:UTF-8(Unicode Transformation Format -8 bit)是一种可变长度的字符编码,用于将Unicode码点转换为字节序列。对于 ASCII 字符(码点
U+0000到U+007F),UTF-8 使用 1 个字节。对于其他字符,UTF-8 使用 2 到 4 个字节。UTF-8 中的 "8" 表示它使用 8 位(1 个字节)作为基本单位(编码并兼容ASCII码)。
使用AI工具优化
由于python没有switch case语句。我代码中的多层if-else语句又显得很丑陋,因此我向MarsCode询问改进方案。她提出可以使用字典改进。以下是我根据建议提出的改进方案(不是模型直出):
def encode(rawStr):
rawBytes = rawStr.encode('utf-8')
rawBytesList = [f"{byte:08b}" for byte in rawBytes]
rawBits = ''.join(rawBytesList)
orginLen = len(rawBits)
lenPadding = (5-len(rawBits) % 5) % 5
rawBits += ("0"*lenPadding)
n = len(rawBits)
res = []
for i in range(n//5):
lo = i*5
hi = (i+1)*5
index = int(rawBits[lo:hi], base=2)
res.append(charSet[index])
res = "".join(res)
remains = orginLen % 40
extra_plus_num = {8:6, 16:4, 24:3, 32:1}
res += "+"*extra_plus_num.get(remains, 0)
return res
def decode_(encodedStr):
codes = [charSet.index(encode) if encode !=
'+' else '+' for encode in encodedStr]
if codes[-6] == "+":
codes = codes[:-6]
remaining = 8
elif codes[-4] == "+":
remaining = 16
codes = codes[:-4]
elif codes[-3] == "+":
remaining = 24
codes = codes[:-3]
elif codes[-1] == "+":
remaining = 32
codes = codes[:-1]
else:
remaining = 0
codesBits = list(map(lambda code: f"{code:05b}", codes))
codesBits = "".join(codesBits)
trunc_map={8:-2, 16:-4, 24:-1, 32:-3}
trunc_idx = trunc_map.get(remaining, None)
if trunc_idx:
codesBits=codesBits[:trunc_idx]
code = int(codesBits, 2).to_bytes((len(codesBits)//8), 'big')
res = code.decode('utf-8')
return res