CodeShell.kr - Residual
Challenge
单张 512×512 PNG,题名暗示同一道痕迹有五种留法。载体结构可以完整解出,但符号到比特的映射尚未确定,本文只写已经验证过的部分。
Five ways to leave the same trace
五种留下同一道痕迹的方式。
1 | https://codeshell.kr/challenges/residual/ |
Solution
唯一附件 residual-final.png(512×512 RGB,330989
bytes)。自解析 PNG 结构:
1 | IHDR 13 IDAT 330932 IEND 0 # 只有三块,无辅助 chunk |
所以载荷只可能在像素值里。题名的「五种方式」对应 PNG 的 5 种行过滤 (None/Sub/Up/Average/Paeth),而 "residual" 就是过滤后的扫描线数据:
1 | filter 直方图 {102, 97, 114, 105, 94} 512 行只有 408 段连续同值 |
注意 408 恰好等于随机 i.i.d.
序列的期望段数(512×(1−5·0.04)=409.6),而
自适应编码器会挑残差最小的过滤器、产生长同值段,所以它确实不像正常编码器的
输出。但 16
种映射(3/2/1-bit、f==0、f==4、相邻是否变化、base-5
与 base-25 大整数)都没有产出可读文本。
通道有序性:三个通道处处满足
R ≤ G ≤ B(R−G ∈ [−25,0]、
G−B ∈ [−46,0]),所以每个像素是累加三元组
(v1, v1+v2, v1+v2+v3)。拆开这三个
分量(含对比度拉伸与位平面)都没有文字。
关键突破:蓝通道几乎恒为偶数。
1 | B bit0 的 1 比例 = 0.0038 -> 262144 像素里只有 995 个蓝通道值为奇数 |
和 Parallax 的 plate 是同一手法,数据写成奇数,所以按常规读 LSB 只会看到 全 0。这 995 个奇点精确构成一个旋转半色调网点阵:
1 | 32 个横向条带:第 b 条覆盖行 16b+8 .. 16b+12(5 行,周期 16) |
网点值直方图 {0:28, 1:157, 2:170, 3:130, 4:27},总和
0+157+340+390+108 = 995 ✓ 与奇点数吻合。值域恰好 5
个等级,与题名呼应。
位点索引方式已全部穷举(每点 5 位行掩码、计数作 3-bit、计数作 base-5 大整数、 最高/最低标记行索引、6 种网格朝向 × 行/列优先 × MSB/LSB、28 个空位点坐标), 均无可打印文本与 magic。
后续六轮验证全部否定:
1 | A. 位置偏差 995 个点全部精确落在理想剪切格上(偏差 {0:995})-> 位置不承载数据 |
下次切入点:offsets 0-3 的 4-bit 字段最像数据域、offset 4 应分开处理;或按 有序抖动矩阵反解 5 级灰度渲染;或把 5 个行偏移当同一数据的 5 份渲染两两求差。