摘要

  • RFC 2395 把 2,048 字节的 LZS 滑动窗口限制在一枚数据报里:发送端压缩前重置,接收端解压前也重置。
  • 强制 flush 确保本包输入不会留到下一包,结束标记则划开有效码流与填充;二者都不是完整性、身份或送达证明。
  • 约 90 字节与 Calgary Corpus 压缩比只是具名实验;协商算法、实际启用、净节省、成功解码和应用结果仍是不同事实。

记住上一包,会把丢包变成连锁故障

LZS 用滑动窗口保存刚见过的字节序列,再用位移和长度代替重复内容。在连续字节流中,窗口越有历史,匹配机会通常越多。但 IP 交付的是独立数据报,而不是承诺有序、无缺口的流。

假如第二包引用第一包建立的字典,第一包一旦丢失,第二包即使完整到达也无法还原。第三包继续引用同一历史,故障还会向后蔓延。压缩层等于偷偷向网络索取了它从未承诺的可靠顺序。

RFC 2395 的办法很直接:发送端在处理每个 payload 前必须重置压缩历史;接收端对每个压缩数据报解码前也必须重置。窗口仍然存在,却只能观察当前包内部的重复。丢一包只丢一包,乱序也不会制造字典分叉。

这种选择牺牲了跨包重复带来的收益,尤其不利于短包。它换来的不是“更安全”这个含糊标签,而是明确的故障半径。算法提供记忆能力,协议配置决定记忆能支配多长时间。

RFC 1967 与 RFC 1974 说明,同叫 LZS 并不等于同一状态模型。PPP 场景可以维护历史编号、序列与复位机制;IPComp 的 RFC 2395 则选择每包独立。名称不是状态寿命的证据。

flush 只证明编码器没有欠下一包

仅仅重置还不够。流式压缩器可能收下全部输入,却暂时扣住少量输出,期待后续字节带来更优编码。对数据报而言,这意味着当前包的一部分要借未来包才能交付。

RFC 2395 因此要求每次发送压缩数据报都 flush。当前输入必须全部出现在当前输出里,不能为了压缩比把数据拖到下一个交付单元。压缩边界由此与数据报边界对齐。

但 flush 的证据范围很窄:它证明编码器没留下输入,不证明网络送达、不证明接收端接受、不证明解压成功,更不证明上层应用完成工作。把“编码已收尾”写成“业务已成功”,只是把内部状态冒充外部结果。

结束标记划开填充,却不鉴别真伪

LZS 码流由原始字节和位移/长度引用组成,末尾有规定的结束标记。码流可能停在一个字节中间,传输却必须使用完整字节,因此后面会出现填充位或填充字节。结束标记让解码器知道真实内容在哪里停止。

这是一条语法边界,不是密码学边界。标记不绑定发送者,不防篡改,不验证原始长度,也不证明解码后的内容符合应用预期。攻击者同样能构造“结尾正确”的码流。它只回答一个问题:LZS 指令到哪里结束。

RFC 2407 把 LZS 变换标识放进当时的 IP 安全协商体系,更容易诱发误解。IPCOMP_LZS 告诉双方采用哪一种解压方法;它没有把压缩变成加密或认证。

协商 LZS,不等于每包都出现 IPComp

RFC 2395 为 ISAKMP 协商和手工配置给出了 LZS 标识,而且不要求额外的 LZS 协商参数。共享上下文建立之后,通用 IPComp 规则仍要逐包比较大小:若压缩 payload 加上 IPComp 头部并不比原始 payload 小,就必须发送原包,并省略 IPComp 头部。

RFC 3173 取代 RFC 2393 后保留了这一非扩张原则。因此,看不到协议号 108 不能推断协商失败;看到它也不能推断解压成功。能力、选择、线上格式、解码与应用效果,各自需要自己的记录。

LZS 本身没有 RFC 所说的自适应“可压缩性测试”。实现可以依据本地历史决定少试某类流量,但那是实现策略,不是算法自动学习,也不是所有节点必须共享的规则。

90 字节必须连同语境一起保存

RFC 记录了 Calgary Corpus 上的非正式实验:平均而言,约 90 字节以下的 payload 可能膨胀,实现可以考虑不尝试压缩。附录还显示,在该语料上,64 字节数据报约为 1.18 的压缩比,16,384 字节则约为 2.14。

趋势并不神秘。每包都清空窗口,长包在下次清空前有更多重复可找;固定头部和结束成本在短包里占比更大。但这些数字只描述具名语料、具名算法和具名包长。

加密数据、已经压缩的图像、短控制消息、二进制协议和刻意构造的输入都可能不同。RFC 2394 的 DEFLATE 配置有自己的实现语境,RFC 3051 后来讨论另一种字典在逐包重置下的成本。RFC 3819 更直接提醒:已经压缩或加密的数据通常没有多少冗余可供下层再利用。

所以 90 不是线上常数,更不是合规门槛。它是本地测量的起点。

技术格式之外,还有当时的采用条件

RFC 2395 当时写明 Hi/fn 持有 LZS 专利,并描述参考实现、源代码/目标代码与硬件许可选项。这段话不改变任何比特,却会影响实现者是否采用。

它也只能作为 1998 年的历史证据。它不能证明今天的权利归属、有效性、费用或许可可得性。旧文档不会自动替法律状态更新自己。

这正符合最小共同规范的边界:共同层规定重置、flush、编码和结束;运营者仍决定阈值、工作负载、许可条件与是否采用。运行中的数据报和应用结果,再检验这些本地决定。

遗忘不是损失,而是拒绝虚构保证

RFC 2395 最耐久的设计不是压缩技巧,而是拒绝让优化扩大失败。它没有逼 IP 为字典提供有序流;它让字典服从 IP 已经提供的数据报边界。

今天复盘这项机制,应分别保留七张收据:算法可用、关联已建、历史已重置、本包是否尝试、码流是否闭合、输出是否成功还原、应用是否得到有用结果。任何一张都不能替其他几张签字。

来源