如何从无文件头的损坏加密JPEG原始数据中获取图像尺寸
首先明确核心前提:标准基线JPEG的宽高参数仅存储在文件头附近的SOF(帧起始)标记段中,你当前前153605字节已经被加密,这部分元数据已经被覆盖,无法直接从原始压缩流的固定偏移位置直接读取尺寸,但可以通过JPEG本身的编码规则推导得到正确参数,可行方法按实操成功率从高到低排列如下:
优先匹配已知来源的固定分辨率
如果这张图来自固定设备(手机、相机、监控)、固定平台导出(社交平台、截图工具、特定网站),这类场景生成的JPEG分辨率通常是固定的几档,优先枚举同来源其他正常图片的分辨率试错,效率最高。同来源JPEG的霍夫曼表、量化表、采样率参数基本完全一致,你可以直接把完好JPEG的文件头(从SOI标记0xFFD8开始,到SOS标记0xFFDA之后的熵编码起始位置前的全部字节)截取出来,替换头里的SOF段宽高字段,拼接到你损坏文件的未加密部分开头,能正常显示无错位的参数就是正确值。基于MCU编码特征暴力枚举匹配
JPEG压缩以最小编码单元(MCU)为单位编码,常见采样率对应的MCU尺寸为:4:2:0采样(90%以上普通彩色JPEG用这个)是1616像素,4:2:2采样是168像素,4:4:4采样是8*8像素。你可以写简单的解码脚本,从剩余未加密数据的起始位置开始,用通用基线JPEG的标准霍夫曼表做熵解码,遍历常见分辨率参数:- 解码过程中不出现非法霍夫曼码、采样值越界错误
- 解码到文件末尾时刚好消耗完所有剩余字节,且最后结束位置刚好落在整数个MCU块边界
满足这两个条件的宽高组合,99%以上就是正确参数。如果加密截断位置刚好落在某个MCU中间,你可以把开头1~100字节逐字节偏移作为解码起点试,误差不会超过3个MCU块的大小。
如果你能在剩余数据里找到重启间隔标记(标记值为0xFFD0~0xFFD7,按固定间隔循环出现),可以直接通过两个重启标记之间的字节数,反推一行对应的MCU数量,计算速度能提升几十倍,不需要全量解码。
肉眼校验解码片段确认参数
如果枚举到的参数接近正确值,你不需要解码全图,只需要解码前几十行像素:当宽度参数正确时,哪怕色彩有偏差、开头有少量花块,你也能看到连续的横向纹理、物体边缘、文字轮廓是水平对齐的;如果宽度错误,解码出来的内容会是倾斜的错位乱纹,很容易肉眼识别。宽度确定后,总高度可以通过剩余文件的总数据量、单位像素压缩后的平均字节数反推得到。
注意:不要直接把其他完好JPEG的文件头硬拼到损坏文件上不修改尺寸,那样得到的图要么拉伸变形,要么整体错位花屏,必须匹配到正确宽高才能完成修复。
内容的提问来源于stack exchange,提问作者Bảo Hoàng

