5.6 程序结构——作业 Base64¶
内容梗概¶
本课讲解本次作业的背景知识——Base64 编码,它是上一次作业(可打印字符转换)的进阶版。老师从 Base64 的历史由来(SMTP 电子邮件协议只能传可打印文本,MIME 补充规范用 Base64 把二进制附件转成可打印文本)讲起,详细拆解了编码算法:选 64 个可打印字符、每 3 字节(24 比特)重新按 6 比特分组、以 6 比特值作下标查表输出,以及不能整除时补零并在末尾加 = 的规则。课上还演示了 Python 内置 base64 库的 b64encode 用法(输入必须是 bytes 类型),作业要求自己写程序模拟这个算法过程。注:本段字幕在讲解补 = 规则后戛然而止,作业的具体提交要求未完整录入。
知识点详解¶
Base64 的由来¶
- Base64 是随着 SMTP(电子邮件协议,用于发邮件;对应的 IMAP 用于收邮件)之后的补充规范 MIME 发明的一种编码方式 (约 00:31–01:54)。
- 早期电子邮件只考虑正文文本:全部是**可打印字符**(能 print 显示出来的字符串),甚至只考虑英文和数字。
- 现代邮件有附件(图片、zip、甚至 exe),它们是
10011001…的**二进制文件**,其中含大量**不可打印字符**——如0x00(C 语言里字符串的结束符),在命令行/记事本里显示不出来。只支持可打印文本的邮件系统发不了这些东西。 - 解决办法(MIME):把二进制文件统一转化成可打印文本再传输,这套统一规则就是 Base64。二进制→可打印文本叫**编码(encode),反过来叫**解码(decode)。
Base64 的编码算法¶
- 选取 64 个可打印符号:大写 A–Z(26)+ 小写 a–z(26)+ 数字 0–9(10)+
+和/,共 64 个 (约 01:58)。 - 编码过程(以单词 "Man" 为例,约 07:33–09:51):
- 每个字符转 ASCII 数字:M=77、a=97、n=110;每个字符 1 字节 = 8 比特。
- 每 3 个字节为一组,共 24 比特。
- 把 24 比特**重新按 6 比特分组**,正好分成 4 组(24 是 6 的整数倍)。
- 6 比特可表示 0–63(2^6=64),正好作为长度 64 的字符表**下标**;把每组 6 比特换算成索引,去字符表中取出对应字符,按顺序输出即得 Base64 编码结果。
- 不能整除(补零与
=填充) (约 10:04–18:00): - 字节数不是 3 的整数倍时,缺的部分全部补 0 比特参与分组,末尾再加等号
=补齐。 - 规则:模 3 余 2(如 5 字节)→ 末尾加 1 个
=;模 3 余 1 → 末尾加 2 个=。 - 所以 Base64 编码结果常常以
=或==结尾。 - 老师画图演示:只剩 1 个字符(M)时,其余位置全当 0,能分出的组照常换算输出字符,剩余组用
=占位补完整。
Python 内置 base64 库演示¶
import base64,调用base64.b64encode(...)即可完成编码 (约 10:47)。- 注意:
b64encode的参数必须是 bytes 类型(bytes-like,二进制数据),不能直接传字符串。写法:在字符串引号前加b,如b"Man\x00..."。bytes 里的值可以是任何字节,包括不可打印的0d、00等(二进制数据类型后续课程才正式讲,这里先强行使用)(约 11:09–13:34)。 - 小测验:示例二进制数据共 5 个字节(注意不可打印字符也各占 1 个字节),5 不能被 3 整除(模 3 余 2),编码结果末尾加 1 个
=。
示例与演示¶
- 用 "Man" 手算 Base64:M/a/n → 77/97/110 → 24 比特 → 重新按 6 比特分 4 组 → 每组作下标查 64 字符表输出。
base64.b64encode(b"...")现场演示编码结果,观察末尾=的个数与字节数模 3 的关系。- 画图演示 5 字节、1 字节等不能整除情形下的补零与补等号过程。
作业要求与解题思路¶
- 作业定位:上一次作业(可打印字符转换)的进阶版——自己写程序实现 Base64 编码,模拟这个算法的过程(“比较硬核”,不直接用内置库交差)。
- 解题思路(依课堂讲解):
- 输入二进制/字符串数据,把每个字节转成 8 位二进制;
- 每 3 字节(24 比特)一组,重新按 6 比特切成 4 段;
- 每段换算成 0–63 的索引,在 64 字符表(A–Z、a–z、0–9、+、/)中查表取字符;
- 字节数模 3 余 2 补 1 个
=、余 1 补 2 个=(缺位按 0 比特处理)。 - 可用内置
base64.b64encode验证自己程序的结果是否正确。 - 注意:字幕文件在补
=规则讲完后即结束,作业的具体提交方式、截止时间等未在字幕中出现。
重点与难点¶
- 理解 Base64 存在的意义:邮件系统只支持可打印文本,二进制附件必须编码后才能传输。
- 核心算法就两步:3 字节变 24 比特、24 比特按 6 比特重分成 4 组查表;6 比特对应 2^6=64 所以叫 Base64。
- 补零与补
=是最容易出错的地方:先补 0 比特凑组,再在结果末尾按余数补=;不可打印字符(如0x00)也是完整的一个字节,计字节数时不能漏。 b64encode只接受 bytes 类型,字符串前要加b前缀。
关联内容¶
- 本次作业是上一次作业(字符串/可打印字符转换)的进阶,继续锻炼循环、切片、取模等基本功(对应 5.3 循环语句中点评的“两字符一组”解法)。
- 涉及的前置知识:ASCII 码(5.1 字符串比较时用过)、二进制与比特(C 语言基础)、bytes 类型(后续课程正式讲)。
- 与 5.5 闲聊 HTTPS 同属网络应用话题:SMTP/IMAP 邮件协议、MIME 规范在后续《计算机网络》课会正式学习;实践部分还会讲用 Python 发邮件(呼应 5.3 的“给尾号为 5 的学号发邮件”例子)。