ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Python批量生成现代密码学课后习题可运行pptx课件

Python批量生成现代密码学课后习题可运行pptx课件 简介这份《现代密码学杨波课后习题讲解PPT课件》面向学习现代密码学课程的高校学生与备考读者聚焦教材习题的完整推导与讲解适合在跟课复习、期末备考或考研复试阶段对照使用。压缩包内仅1个pptx文件约1.02MB以幻灯片形式分章呈现图文对照便于课堂演示与自学翻阅。内容围绕仿射密码、多表代换密码、流密码与线性反馈移位寄存器等基础理论展开从E11,23的加密与模逆元解密验证到由已知明文密文对反推2×2矩阵A、3级LFSR不同反馈函数的输出序列与周期分析再到DES解密变换的证明均给出逐步解法与关键公式。读者可借此理清模运算、特征多项式、密钥流生成等易错环节的解题思路形成可直接对照的习题笔记。目前已有1712人学习。1. 从一道 RSA 课后习题说起现代密码学课件为什么值得做成可运行的 pptx期末前一周很多人对着杨波《现代密码学》的课后习题卡住题干只有三行给定两个素数和一个公钥指数要求出私钥、解出明文。真动手才发现答题纸要写满一页扩展欧几里得迭代表中间任何一个余数抄错最后的明文就是一串乱码。更麻烦的是习题课只有九十分钟讲台上照着答案念一遍台下抄完还是不会。把这类课后习题做成一份可运行的 pptx 课件解决的正是这个断层。每一页对应一道题题干、手算迭代、Python 复算结果、易错点四块并排摆开放映时能直接跳到代码跑一遍学生看到的不再是「答案是对的」而是「每一步为什么这么算」。这份课件适合三类人要串讲习题的助教、准备期末或考研复试的学生、以及想把数论和密码学基础重新捡一遍的工程师。2. 现代密码学课后习题的题型地图与 pptx 课件骨架设计2.1 五类高频题型与各自的计算量杨波《现代密码学》的课后题大致落在五个区域。数论基础题模运算、扩展欧几里得、中国剩余定理占比最高单题手算两到五分钟RSA 与公钥体制题通常一道题串起密钥生成、加密、签名三个小问分组密码与流密码题偏重过程推演比如给定反馈多项式求 LFSR 的输出序列哈希与消息认证题多考生日攻击的概率估算和 MAC 构造协议分析题要求指出某段交互流程的安全缺陷。题型典型考点手算耗时代码验证价值数论基础扩展欧几里得、模逆、CRT2–5 分钟高迭代过程可逐行打印RSA/公钥密钥生成、加解密、签名5–15 分钟高参数一改就错流密码/分组密码LFSR 序列、DES、AES8–20 分钟中需对照标准向量哈希/MAC生日攻击、HMAC3–8 分钟中概率值可计算协议分析重放、中间人、认证缺陷不定低靠逻辑推演这张表直接决定课件页面的分配策略。数论和 RSA 两类值得每题都配代码页因为结果是确定的、可校验的协议分析题更适合画时序图和攻击路径不必强上代码。2.2 一页一题的课件页面结构常见做法是把每道题拆成四页而不是把答案堆在一页里。第一页只放题干和已知条件字号放大到 24 磅以上让学生先看清参数第二页放手算推导用表格呈现扩展欧几里得的每一轮迭代第三页放代码和运行输出终端结果直接粘贴成等宽文本第四页收易错点比如「模逆存在的前提是 gcd(a, m) 1」这类一句话提醒。四页结构有个实际好处讲到第二页时可以让学生先自己算一遍再放第三页对答案节奏天然对上。如果课时紧可以把第三、四页合并但题干页和推导页不要合并混在一起学生找不到参数。页面右下角建议留一个固定的题号角标翻页时能立刻确认当前讲到哪一题。2.3 python-pptx 生成课件骨架的最小可运行脚本手搓几十页 PPT 不现实常见做法是用 python-pptx 从一份 JSON 题库文件批量生成。下面是最小骨架先把标题页和内容页跑通再往里填题。# build_deck.py from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN # 新建一份 16:9 文稿后续所有页都往这里加 prs Presentation() prs.slide_width Inches(13.333) prs.slide_height Inches(7.5) blank prs.slide_layouts[6] # 6 号版式是纯空白便于绝对定位 def add_title_slide(title, subtitle): slide prs.slides.add_slide(blank) box slide.shapes.add_textbox(Inches(1), Inches(2.8), Inches(11.3), Inches(1.5)) tf box.text_frame tf.text title tf.paragraphs[0].font.size Pt(40) tf.paragraphs[0].alignment PP_ALIGN.CENTER sub slide.shapes.add_textbox(Inches(1), Inches(4.3), Inches(11.3), Inches(0.8)) sub.text_frame.text subtitle sub.text_frame.paragraphs[0].font.size Pt(20) def add_problem_slide(pid, stem, params): slide prs.slides.add_slide(blank) head slide.shapes.add_textbox(Inches(0.6), Inches(0.4), Inches(12), Inches(0.8)) head.text_frame.text f{pid} {stem} head.text_frame.paragraphs[0].font.size Pt(26) body slide.shapes.add_textbox(Inches(0.6), Inches(1.5), Inches(12), Inches(5)) tf body.text_frame for k, v in params.items(): # 已知条件逐行铺开字号统一 p tf.add_paragraph() p.text f{k} {v} p.font.size Pt(22) return slide add_title_slide(现代密码学课后习题讲解, 杨波《现代密码学》配套习题课) add_problem_slide(习题 4-3, RSA 密钥生成与解密, {p: 47, q: 71, e: 79, c: 1234}) prs.save(现代密码学课后习题讲解.pptx)Presentation()对象一旦创建所有add_slide都往同一份文稿里写所以题库循环可以放在最外层。slide_layouts[6]是默认模板里的空白版式索引在不同模板上可能不同换模板时先打印len(prs.slide_layouts)确认。Inches和Pt是长度单位对象不能直接传整数传1只会得到 1 EMU页面上什么都看不到。字号方面题干页 24 磅起参数行 22 磅低于 18 磅投影仪后排就看不清。提示模板文件如果自带占位符add_textbox生成的文本框会和占位符重叠排版看起来像重影。用纯空白版式最省心。3. 用 Python 复算课后习题模逆、RSA 与分组密码的核心代码3.1 扩展欧几里得与模逆的手算对齐讲扩展欧几里得时课件最怕「代码算出来了但过程对不上」。让代码把每轮迭代打印成表和手算表格逐行对齐这个问题就没了。def egcd(a, b, traceNone): 返回 (g, x, y) 使得 a*x b*y g gcd(a, b) old_r, r a, b old_s, s 1, 0 old_t, t 0, 1 while r ! 0: q old_r // r old_r, r r, old_r - q * r old_s, s s, old_s - q * s old_t, t t, old_t - q * t if trace is not None: trace.append((q, old_r, r, old_s, old_t)) return old_r, old_s, old_t def modinv(a, m): g, x, _ egcd(a, m) if g ! 1: raise ValueError(f模逆不存在gcd({a}, {m}) {g}) # 必须显式报错 return x % m trace [] print(egcd(47, 71, trace)) for row in trace: print(row) print(modinv(79, 46 * 70))egcd里的old_前缀变量保存上一轮的值q是当前商每一轮同时更新余数和两个系数这正是手算表格里「商、余数、系数 s、系数 t」四列。trace参数可选只在需要生成课件表格时传入正常调用不传能省掉内存开销。modinv里那句异常不能省。课件上如果只写x % m遇到gcd(a, m) ! 1的题会算出一个看起来正常的数学生照着抄就错了。Python 3.8 之后内置了pow(a, -1, m)行为一致但课件要展示推导过程还是自己写一份更直观。3.2 RSA 课后题的完整复算链路RSA 题目一条龙写下来不到三十行关键是每个中间量都留痕方便直接塞进 PPT 表格。from math import gcd def rsa_keygen(p, q, e): n p * q phi (p - 1) * (q - 1) assert gcd(e, phi) 1, e 与 φ(n) 不互素换一个 e d modinv(e, phi) return {n: n, phi: phi, e: e, d: d} def rsa_encrypt(m, e, n): assert 0 m n, 明文必须小于 n return pow(m, e, n) def rsa_decrypt(c, d, n): return pow(c, d, n) keys rsa_keygen(47, 71, 79) print(keys) # {n: 3337, phi: 3220, e: 79, d: 1019} c rsa_encrypt(688, keys[e], keys[n]) print(c, rsa_decrypt(c, keys[d], keys[n]))pow(m, e, n)是模幂运算三项参数版本走的是快速幂和手算时反复平方的做法完全一致可以直接对照。assert 0 m n这句在课件里要强调明文分组长度必须小于模数真做题时如果明文比 n 大要么换更大的素数要么先分组。中间量手算来源代码对应位置np × qrsa_keygen的nφ(n)(p−1)(q−1)rsa_keygen的phide 在模 φ(n) 下的逆modinv(e, phi)cm^e mod nrsa_encrypt返回值mc^d mod nrsa_decrypt返回值密钥生成里的d modinv(e, phi)有时也可以用d pow(e, -1, phi)替代。两种写法结果一样但前者能顺带输出扩展欧几里得的迭代表讲课时过程感更强。3.3 流密码与分组密码习题LFSR 序列与 AES 调用的复现LFSR 题目通常是给定级数、反馈多项式和初态求前 N 位输出。用位运算写十行就够。def lfsr(seed, taps, n): seed: 初态整数; taps: 抽头位置(1 起); n: 输出位数 state seed bits [] deg seed.bit_length() for _ in range(n): out state 1 bits.append(out) fb 0 for t in taps: fb ^ (state (t - 1)) 1 # 按抽头异或得到反馈位 state (state 1) | (fb (deg - 1)) return bits print(lfsr(0b1001, [1, 4], 15)) # 输出前 15 位密钥流taps用 1 起的编号是为了和教材上的抽头下标对应代码里统一右移t-1位取出。deg由初态的二进制长度决定如果题目给的初态高位是 0bit_length()会算短这时改成显式传级数更稳。输出序列在课件里建议用一张时序表横向排开标出每一位对应的寄存器状态。AES 这类题一般要求验证标准向量直接调库比手写轮函数靠谱得多。from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad key bytes.fromhex(000102030405060708090a0b0c0d0e0f) iv bytes.fromhex(101112131415161718191a1b1c1d1e1f) cipher AES.new(key, AES.MODE_CBC, iv) ct cipher.encrypt(pad(bmodern cryptography, 16)) print(ct.hex()) pt unpad(AES.new(key, AES.MODE_CBC, iv).decrypt(ct), 16) print(pt)这段用了 pycryptodome 的Crypto命名空间如果运行时报模块找不到说明装的是 pycryptodomex把导入改成Cryptodome即可。pad和unpad必须成对使用PPT 上要写清楚分组密码只管加密填充属于模式层的事混在一起讲学生容易把填充也算进轮函数。3.4 椭圆曲线点加与离散对数题的实现思路椭圆曲线习题常要求验证点加公式或穷举小阶群的离散对数。模 p 下的点加写成函数结果和手算的斜率公式能一一对应。def ec_add(P, Q, a, p): 在 y^2 x^3 a*x b (mod p) 上做点加O 用 None 表示 if P is None: return Q if Q is None: return P x1, y1 P x2, y2 Q if x1 x2 and (y1 y2) % p 0: return None # 互为逆元结果为无穷远点 if P Q: lam (3 * x1 * x1 a) * pow(2 * y1, -1, p) % p # 切线斜率 else: lam (y2 - y1) * pow(x2 - x1, -1, p) % p # 割线斜率 x3 (lam * lam - x1 - x2) % p y3 (lam * (x1 - x3) - y1) % p return (x3, y3) print(ec_add((5, 1), (5, 1), 2, 17)) # 倍点pow(v, -1, p)直接给出模 p 的逆省掉手写模逆。分支里(y1 y2) % p 0处理的是两个点 x 相同、y 互为相反数的情况此时连线垂直于 x 轴交于无穷远点返回None。这个分支在课件上一定要单独列一页学生手算时最容易漏。离散对数题如果阶数很小直接穷举k跑一遍k*P就行阶数稍大可以上 BSGS大步小步。课件里放穷举版本足够重点是让学生看到「已知 P 和 Q找 k」这件事在没有陷门时有多慢。真做题时还要注意无穷远点不能参与后续运算参与前先判空。4. 公式图、密钥流示意图与代码高亮pptx 讲清推导过程的渲染细节4.1 用 mathtext 把模运算公式渲染成透明背景 PNGPPT 自带的公式编辑器在批量生成场景下不好用常见做法是用 matplotlib 的 mathtext 把公式渲染成 PNG 再贴进去。import matplotlib matplotlib.use(Agg) # 无界面后端服务器上也能跑 import matplotlib.pyplot as plt def render_formula(tex, path, fontsize18): fig plt.figure(figsize(0.01, 0.01)) fig.text(0, 0, tex, fontsizefontsize) fig.savefig(path, dpi300, transparentTrue, bbox_inchestight, pad_inches0.05) plt.close(fig) render_formula(r$d \equiv e^{-1} \bmod \varphi(n)$, formula_d.png)参数建议取值影响dpi300投影清晰度与文件体积的平衡点transparentTrue贴图不带白底能压在配色背景上bbox_inchestight裁掉四周多余留白缩放时好对齐pad_inches0.05公式边缘留一点空隙不至于贴边fontsize16–20与正文字号协调太小投影看不清matplotlib.use(Agg)必须在import pyplot之前调用顺序反了在某些环境上会报后端错误。mathtext 用的是 matplotlib 自己的一套 LaTeX 子集\bmod能用但\pmod不一定支持遇到不认的命令会直接抛语法错报错信息里会指出位置。稳妥做法是拆成两段文本渲染或者写成\ (\mathrm{mod}\ n)绕过去。4.2 画密钥流与分组结构的示意图LFSR 的抽头结构用几行 matplotlib 就能画清楚比文字描述直观得多。import matplotlib.pyplot as plt def draw_lfsr(taps, stages, path): fig, ax plt.subplots(figsize(6, 2)) for i in range(stages): ax.add_patch(plt.Rectangle((i * 1.0, 0), 0.8, 0.8, fillFalse)) ax.text(i * 1.0 0.4, 0.4, fs{i1}, hacenter, vacenter) y_line -0.6 ax.plot([0.4, stages - 0.6], [y_line, y_line], colorblack) for t in taps: x (t - 1) * 1.0 0.4 ax.plot([x, x], [0, y_line], colorblack) ax.plot(x, y_line, markero, colorblack) # 抽头节点 ax.set_xlim(-0.5, stages 0.2) ax.set_ylim(-1.2, 1.2) ax.axis(off) fig.savefig(path, dpi200, bbox_inchestight) plt.close(fig) draw_lfsr([1, 4], 4, lfsr.png)每个寄存器画成方框抽头位置从方框底边引一条竖线到公共反馈线上节点用实心圆标注。axis(off)关掉坐标轴图更干净。figsize控制宽高比LFSR 这类横长的图用 3:1 左右合适贴到 16:9 的幻灯片上不会被拉变形。如果要在图上叠加具体数值ax.text的坐标和寄存器位置对齐时记得留出 0.4 的偏移否则文字会压在方框边线上。4.3 代码块高亮与字体设置把代码贴进 PPT最常见的问题是缩进丢失和字体不等宽。用Consolas、JetBrains Mono这类等宽字体配合统一行距可读性会好很多。from pptx.util import Pt from pptx.dml.color import RGBColor def set_code_style(paragraph): paragraph.font.name Consolas # 等宽字体缩进才对齐 paragraph.font.size Pt(16) paragraph.font.color.rgb RGBColor(0x1E, 0x1E, 0x1E) paragraph.line_spacing 1.05font.name只对西文生效如果代码里混了中文注释还要单独设置东亚字体否则中文会退回到默认宋体和代码部分明显不协调。行距设成 1.05 到 1.1 之间太松一页放不下二十行太挤行与行会贴在一起。代码块宽度也要控制一行超过 78 个字符在 16 磅字号下会超出幻灯片边界。生成前用max(len(line) for line in code.splitlines())检查一次超了就手动折行别指望放映时自动缩排。5. 批量生成整套课件与答案一致性校验的落地技巧5.1 一题一函数一页的目录约定课件做到十几题之后维护成本主要来自「改了一处参数忘了同步另一处」。用固定目录约定能把这个风险压下去。crypto_slides/ problems/ __init__.py ch03_egcd_01.py ch04_rsa_01.py assets/ formula/ diagram/ build_deck.py cases.json每个题目脚本暴露一个solve()返回字典键就是课件要展示的中间量。# problems/ch04_rsa_01.py from problems.ch03_egcd_01 import modinv def solve(): p, q, e, m 47, 71, 79, 688 n p * q phi (p - 1) * (q - 1) d modinv(e, phi) c pow(m, e, n) return {n: n, phi: phi, d: d, c: c, m_dec: pow(c, d, n)}cases.json里存题号、题干、参数和期望答案build_deck.py负责导入、渲染、排版。这样课件页面里的每一个数字都来自同一个函数返回值不存在两处手抄对不上的问题。5.2 让课件答案和代码输出对得上的校验脚本批量生成之前跑一遍校验比放映当天发现错误划算得多。import importlib, json with open(cases.json, encodingutf-8) as f: cases json.load(f) fail [] for case in cases: mod importlib.import_module(fproblems.{case[module]}) got mod.solve() for k, exp in case[expected].items(): if got.get(k) ! exp: fail.append((case[id], k, exp, got.get(k))) print(不一致条目:, fail)校验项数据来源失败时的典型表现中间量 n、phisolve()返回值课件参数与代码参数不同步加解密互逆m_dec m模逆算错或明文越界公式图文件是否存在assets/formula/PPT 里出现空白占位代码行宽solve()源文件代码页右侧被裁掉importlib.import_module要求problems目录下有__init__.py否则导入会失败。用例的键名要和solve()返回的键完全一致多一个下划线都会判为不一致。校验通过后再跑build_deck.py顺序别反。5.3 实际会踩的四个坑编码问题打开题库文件不写encodingutf-8中文题干在部分系统上会变成乱码json.load直接抛异常。生成 pptx 时文件名带中文没问题但路径里如果有空格某些批处理脚本会截断。大数溢出Python 整数没有上限但把结果写进表格或数据库时可能超范围。课件里的n超过 64 位时不要用int64存直接用字符串。mathtext 语法$配不成对、命令拼错都会报错。渲染前把公式字符串单独跑一遍比在生成 PPT 时才发现要快得多。字体缺失换一台机器放映Consolas不存在时会退回默认字体缩进全乱。生成完在目标机器上放一遍全屏预览确认代码页没有跑版如果放映端字体确实不可控就用 Pygments 把代码渲染成 PNG 贴进页面图片自带字形不依赖放映端装了什么字体。本文还有配套的精品资源点击获取
返回列表