附录 G · 练习与自测(含参考答案)#

本附录把全书最重要的知识点收成一组自测题,覆盖“隐写 vs 加密 / LSB 与统计指纹 / 矩阵编码 / nsF5 与湿纸 / 哈希键控 / 机器学习评估”六块。先自己答,再对照参考答案; 每道题都标注了对应章节,答不上的地方回到那一章重读。

使用建议| 每题先看题干、自己写答案或手算,再看解析。解析里给的代码都能在项目里直接跑。

G.1 隐写 vs 加密(第 3 章)#

题 1 用一句话说出“加密”和“隐写”保护的对象分别是什么,并说明为什么推荐“先加密、再隐写”。

参考答案
  • 加密保护的是“内容”:没有密钥就读不懂明文。

  • 隐写保护的是“存在”:让别人看不出有秘密。

  • 先加密再隐写:密文近似随机比特,反而更不容易在统计上露馅,所以二者通常搭配使用(见 3.1)。

题 2 判断对错并说明理由:“LSB 隐写利用了视觉冗余,却破坏了统计冗余。”

参考答案

对。人眼对 1 级灰度差无感(视觉冗余),所以改 LSB 看不见;但 LSB 替换会把相邻灰度对的 奇偶频数“拉平”、破坏位面的空间结构(统计冗余),这正是卡方检验与 RS 分析能抓住的指纹 (见 3.3、3.4)。

G.2 LSB 与统计指纹(第 3 章)#

题 3 一张图做 LSB 替换后,卡方检验的 p 值会怎么变?为什么?p 值高等于安全吗?

参考答案
  • LSB 替换会强制把相邻灰度对 (2i, 2i+1) 的奇偶频数拉向均衡,卡方统计量变小、p 值升高。

  • 不等于安全:天然噪声图(数码照片)本身 LSB 就接近随机,p 本来就高。所以项目引入 “内容本底随机度”(灰度差分熵)修正,先判断图像本身有多随机,再决定是否把高 p 当作嵌入证据 (见 3.3 末尾避坑提醒)。

题 4 RS 分析里的 \(G_n\) 在“干净图”和“藏过东西的图”上分别趋于什么?背后的原因?

参考答案

干净自然图像 LSB 位面有空间结构,用负掩码翻转后大量组从“常规”变“奇异”,所以 \(G_n=(R_n-S_n)/n\) 明显为正(干净平滑图常在 0.3~0.7)。LSB 随机化后位面结构“塌缩”,正反掩码效果趋同,\(G_n\) 接近 0 (见 3.4)。

G.3 矩阵编码(第 4 章)#

题 5 用 p=3 的汉明矩阵,写出能藏几位、块长多少;并解释为什么“翻 1 列”就能实现目标伴随式。

参考答案

p=3 时块长 \(n=2^p-1=7\),能藏 \(p=3\) 位。把当前 LSB 块 \(x\) 算伴随式 \(s=Hx\),再与想藏的消息 \(m\) 异或得 差分 \(d=s\oplus m\);\(H\) 的每一列是一个 3 位二进制,只要 \(d\) 恰等于某一列(或若干列的异或),翻那一列 对应的像素就能让 \(Hx'=m\)。通常只需翻 1 个像素(见 4.1、4.2)。

题 6 矩阵编码为什么比朴素 LSB“藏得更多、改得更少”?

参考答案

朴素 LSB 是 1 像素藏 1 位、改 1 个像素;矩阵编码把 p 位消息分摊到 \(n=2^p-1\) 个像素的 LSB 块上, 期望只需翻约 \(1-2^{-p}\) 个像素。于是“每改动携带的比特数”(嵌入效率)随 p 增大而明显上升 (见 4.2 的图 4-2)。

G.4 nsF5 与湿纸(第 5 章)#

题 7 nsF5 的“湿点/干点”是如何划分的?为什么“先划湿点”就不收缩了?

参考答案

令 \(xv=\) 像素 \(-128\),定义湿点为 \(|xv|\le1\)(像素 127/128/129)——对它减幅会撞向非法值/0; 干点为 \(|xv|>1\)(见 5.1)。嵌入只在干点上求解(湿纸编码),因此不会“改到一半才发现撞零”, 每个块都能成功嵌入,既不用重试,也不会产生多余的 0 系数,从而不收缩(见 5.2、5.3)。

题 8 湿纸编码“解不出解”的数学本质是什么?

参考答案

要解 \(Hy=d\),但只能用在干列上。干列张成的空间维数 = 干列矩阵的秩 \(r\);当 \(r<p\)(干点不够)时, 某些 \(d\) 落到干列张成的子空间之外,无解(见 5.6)。这正是“干点不足”的数学本质。

G.5 哈希键控(第 6 章)#

题 9 图像哈希键控解决了什么问题?它的局限是什么?

参考答案

嵌入位置由口令派生并经置换决定(permute_index,splitmix64 + Fisher–Yates),所以:

  • 解决:解码端无需记录每个消息块的位置,靠口令即可“自同步”地还原位置(见 6.2);

  • 局限:密码学强度取决于口令本身;口令弱/泄露则位置可被预测。哈希键控给出的是不可预测的位置, 不是“藏得看不见”(见 6 章读图要点)。

G.6 机器学习评估(第 7–8 章)#

题 10 为什么切分数据必须按 photo_id 分组(GroupKFold),而不是随机 KFold?

参考答案

同一张照片的多个变体高度相似;随机切分会把“亲兄弟”拆到训练/测试两侧导致数据泄漏,分数虚高。 按 photo_id 分组把同一照片的所有变体放进同一折,得到的 OOF 分数才诚实(见 7.6、7.7)。

题 11 类别不平衡时,为什么“准确率”会骗人?该看哪些指标?

参考答案

若含密样本远多于干净样本,模型全判“含密”也能拿到高准确率,但把所有干净图都误报了。 应看 AUC(排序能力,与阈值无关)、精确率/召回率、F1 等(见 7.7.3、8.5)。

题 12 AUC=0.7 大概意味着什么?部署时为什么还要再选一个具体阈值?

参考答案

AUC=0.7 表示:随机抽一张含密、一张干净,模型把含密排在干净前面的概率约 70%——多数时候排对了, 但还不够好(弱密度难检出的现实,见 7.7.1)。AUC 与阈值无关,但部署必须定一个阈值:调高→保守(误报少、 漏报多),调低→激进(检出多、误报多),本质是在误报与漏报间选操作点(见 7.7.2、8.6)。

G.7 综合实验(第 10 章)#

题 13 设计一个“证明我的特征确实有用”的最小诚实实验,说明必须在哪些地方守住一致性。

参考答案

用 make_dataset.py 生成同一批照片的干净/含密变体 → 提取特征(基线 vs 你新增的特征)→ 同一组 test-photo 分组 + 5 折 GroupKFold OOF 对比 AUC → 用独立的 held-out 测试集只评估一次。 关键守则:训练/校准/测试三分离;选阈值在训练池内再切出校准集;测试集只能评测一次(否则会“脏”)。 具体见 8.8 与 10 章的诚实评估流水线(图 10-1)。

给自己打分| 13 题全部能答出并举例 → 你已经能“带人复述”这套知识;答不出的题请回到对应章节, 结合“想一想 / 动手做”再读一遍。全部通过后,回到导读 0.4,给自己发一张“入门结业证”。