“迁移到 $b=256,M=4096,L=2^{23}$ 时,窗口上界为 $2^{31}$;阈值上界同为 $2^{31}$,可用64位中间量、32位状态安全实现。检查器的通用核心实际跑这个参数…”
形式陈述
解码正确性说“合法输入恢复原文”;资源契约还要说“面对不合法或巨大展开的输入,在有限工作和内存中停止”。本页把解压看成受预算限制的状态机,接受压缩输入和调用者给出的上限,返回完整结果或明确失败。文件头里的原长是待检查的声明,不能充当可信授权。
至少分别限制:输入字节或有效位数
设已产出
再扩容、创建临时对象和执行循环。用减法形式可避免固定宽度下
对LZ77回指,先验证距离
直觉
压缩文件很短,正是因为一个小指令能代表很多输出。输入大小不再是工作量的好替代物。距离1的回指只需说明“继续重复刚才那个字节”,却可能请求一百万次写入。
越早检查越有用。如果先创建一百万字节的临时数组再检查容量,失败虽被报告,资源已经花掉。如果相信头部写着四十亿就直接分配四十亿容量,一个从未解出任何有效数据的文件也能消耗巨量内存。
预算必须属于本次调用或整条处理链的共享状态。每解一小块就把预算重置,会允许攻击者通过许多块绕过总量上限;嵌套压缩也需跨层累计,否则每层各自看起来“小”并不限制最终展开。
例子与边界
按照“每token1步,每输出字节1步”的模型,Lit(A), Lit(B), Match(7,2) 有3个token、9字节输出,总工作12。若
另一个恶意token序列是 Lit(A), Match(10^30,1)。距离1合法,问题在于长度。检查器用Python大整数先比较
LZ78接到指向现有长短语的END时,即使不新增字典条目,仍须支付这个短语的输出和父链遍历费用;“结束token免费”会漏掉最后一段。字典上限也和输出上限不同:许多短而不同的短语可以使条目数快速增长,单看某次匹配长度不够。
对Huffman/算术帧,声明原长 '0'/'1' 字符串前核对物理payload长度。这个字符串表示只为演示,生产流式解析通常直接从字节取bit。
推论与应用
可检验的资源上界
在每个动作之前扣减预算,归纳可得:任意成功前缀的累计输出不超过
固定精度的算术解码,每个符号的重归一化次数为
若把结果流式写给下一环节,出错前已经交付的前缀可能无法撤回。需要“全部有效才交付”的调用契约时,应写入有上限的临时输出,再在EOF和帧校验通过后发布;也可以明确允许调用者收到部分结果及失败状态。资源检查不自动提供事务语义。
绝对上限与工作上限是安全边界;压缩比上限可以是额外策略,但会拒绝合法的高压缩重复内容,也不能替代最大展开字节数。检查器通过有限枚举和恶意长度用例展示检查顺序,不宣称测试已经证明任意第三方解压器安全。