项目挑战拓展项目之Base64编码原理
说在前面
《浙江省普通高中学科教学指导意见》对“教学要求”的一个重要说明是“认识在真实问题活动情境中解决问题的重要教学价值,发展学生面对真实情境界定问题、抽象与建模、设计算法并解决问题的计算思维。”
将教材中的”问题与挑战“、“问题与讨论”、“实践与体验”、“思考与练习”、“项目挑战”、“拓展项目”等活动合理地融入教学,使学生在真实情境中发现问题,借助问题的探究,发展学生对算法和程序等核心学科概念的深入理解,并掌握相关方法和技能,进一步发展计算思维,形成利用计算思维解决问题的能力。
《信息技术必修一 数据与计算》(浙教版)第一章 项目挑战中有一个拓展项目“Base64编码”,要求学生通过阅读素材和查阅资料,理解Base64编码原理,并实现ASCII字符串与Base64编码字符串的相互转换。
此项目涉及到进制转换和编码解码等重要知识点,虽然难度较高,但是值得广大师生研究。对其加以简化和改编后,更可以命制不同难度的题目。
上面是按照三个字节来举例说明的,如果字节数不足三个,又该如何处理呢?
一个字节:一个字节共8个二进制位,依旧按照规则进行分组。此时共8个二进制位,每6个一组,则第二组缺少4位,用0补齐,得到两个Base64编码,而后面两组没有对应数据,都用“=”补上。因此,上图中“A”转换之后为“QQ==”;
两个字节:两个字节共16个二进制位,依旧按照规则进行分组。此时总共16个二进制位,每6个一组,则第三组缺少2位,用0补齐,得到三个Base64编码,第四组完全没有数据则用“=”补上。因此,上图中“BC”转换之后为“QKM=”。
常见问题
仔细阅读上述资料,回答下列问题:
(1) 字符”Love”的Base64编码为多少?
(2) 若某字符的Base64编码为”QW55”,则其原文是什么?
(3) 请编写程序将ASCII字符串转换成Base64编码字符串。函数头说明如下:
函数功能:将ASCII字符串转换成Base64编码字符串
函数名:ASCII_to_Base64(a)
参数表:a –– ASCII字符串。
返回值:Base64编码字符串。
例1,当a ="Web"时,返回"V2Vi";
例1,当a ="A"时,返回"QQ==";
例3,当a ="AB"时,返回"QUI="。
(4) 请编写程序将Base64编码字符串转换成ASCII字符串。函数头说明如下:
函数功能:将Base64编码字符串转换成ASCII字符串
函数名:Base64_to_ASCII(b)
参数表:b –– Base64编码字符串。
返回值:ASCII字符串。
例1,当b ="V2Vi"时,返回"Web";
例1,当b ="QQ=="时,返回"A";
例3,当b ="QUI="时,返回"AB"。
参考代码
#!/usr/bin/python3
# 文件名: Base64编码
# 作者:巧若拙
# 时间:2022-3-1
'''描述:Base64编码是使用64个可打印ASCII字符(A-Z、a-z、0-9、+、/)
将任意字节序列数据编码成ASCII字符串,另有“=”符号用作后缀用途。
Base64将输入字符串按字节切分,取得每个字节对应的二进制值(若不足8比特则高位补0),
然后将这些二进制数值串联起来,再按照6比特一组进行切分(因为2^6=64),
最后一组若不足6比特则末尾补0。
将每组二进制值转换成十进制,然后在上述表格中找到对应的符号并串联起来就是Base64编码结果。
由于二进制数据是按照8比特一组进行传输,
因此Base64按照6比特一组切分的二进制数据必须是24比特的倍数(6和8的最小公倍数)。
24比特就是3个字节,若原字节序列数据长度不是3的倍数时且剩下1个输入数据,
则在编码结果后加2个=;
若剩下2个输入数据,则在编码结果后加1个=。
'''
'''
函数功能:将二进制字符串长度凑成n的倍数,不足n位则高位补0
函数名:to_Byte(bc, n)
参数表:bc –– 二进制字符串;
n –– 每组字符串的长度;
返回值:高位补0后的二进制字符串,其长度位n的倍数。
例1,当bc="101010101010",n=8时,返回"0000101010101010";
例1,当bc="11010",n=6时,返回"011010";
例3,当bc="110100",n=6时,返回"110100"。
'''
def to_Byte(bc, n):
m = (n - len(bc) % n) % n #前缀0数量,也可以写成(n - len(bc)) % n
ans = '0' * m
return ans + bc
'''
函数功能:将ASCII字符串转换成Base64编码字符串
函数名:ASCII_to_Base64(a)
参数表:a –– ASCII字符串。
返回值:Base64编码字符串。
例1,当a = "Web"时,返回"V2Vi";
例1,当a = "A"时,返回"QQ==";
例3,当a = "AB"时,返回"QUI="。
'''
def ASCII_to_Base64(a):
bite_code = [] #用来存储二进制位
for ch in a:
ac = ord(ch) #ASCII 数值
bc = to_Byte(bin(ac)[2:], 8) #将二进制字符串凑成整数个字节
bite_code.append(bc)
bite_code = "".join(bite_code) #拼接成二进制字符串
n = len(bite_code) #二进制字符串长度
ans = []
c = 0
while c + 24 <= n: #24位一组
group = bite_code[c:c+24] #24位二进制数
for k in range(0, 24, 6):
i = int(group[k:k+6], 2)
ans.append(Base64[i]) #转换成Base64编码
c += 24
m = (n - c)//8 #剩余字节数量,取值为1或2
if m > 0:
group = bite_code[c:] + '00' * (3-m)
for k in range(0, 6*(m+1), 6):
i = int(group[k:k+6], 2)
ans.append(Base64[i])
ans.extend(['='*(3-m)]) #缺失字节补上=
return "".join(ans)
'''
函数功能:将Base64编码字符串转换成ASCII字符串
函数名:Base64_to_ASCII(b)
参数表:b –– Base64编码字符串。
返回值:ASCII字符串。
例1,当b = "V2Vi"时,返回"Web";
例1,当b = "QQ=="时,返回"A";
例3,当b = "QUI="时,返回"AB"。
'''
def Base64_to_ASCII(b):
pass #此处代码就作为课后练习吧
#主函数部分
#创建Base64编码表
Base64 = [chr(ord("A")+i) for i in range(26)]
Base64 += [chr(ord("a")+i) for i in range(26)]
Base64 += [chr(ord("0")+i) for i in range(10)]
Base64 += ['+','/']
#测试代码
p = "A"
b = ASCII_to_Base64(p)
a = Base64_to_ASCII(b)
print(p, b, a)
p = "AB"
b = ASCII_to_Base64(p)
a = Base64_to_ASCII(b)
print(p, b, a)
p = "Web"
b = ASCII_to_Base64(p)
a = Base64_to_ASCII(b)
print(p, b, a)
p = "Love"
b = ASCII_to_Base64(p)
a = Base64_to_ASCII(b)
print(p, b, a)
print("QW55",Base64_to_ASCII("QW55"))
需要本文PPT、源代码和课后练习答案的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注Python算法,感兴趣就一起来!
相关优秀文章: