历史上的 Unix compress 工具会写入通常命名为
.Z 的文件。它使用 LZW 系列字典编码器,而不是 DEFLATE。uncompress 和
zcat 在提供该格式的系统上公开兼容的命令行接口。
LZW 初始化与同步 #
LZW 编码器从单字节字母表的条目开始。它维护当前短语 w,读取下一个字节
k,并在 w + k 位于字典中时继续处理。当该短语不存在时,它输出
w 的代码,添加 w + k,并从 k 开始。解码器输出每个代码对应的字符串;在第一个代码之后,它会添加前一个解码字符串与当前字符串的第一个字节。输入耗尽后,编码器输出其最终短语。因此,编码器和解码器会相差一个代码地添加相同的条目。
常见的 KwKwK 情况发生在某个代码等于下一个字典索引时:解码器会将其展开为
previous + first(previous)。拒绝这种情况会拒绝有效的数据流;接受任何超过下一个索引的代码则会导致字典失去同步。
.Z 位流
#
.Z 数据流以 1f 9d 和一个标志字节开头。低五位指定最大代码宽度,通常为 9 至 16 位。第 7 位启用块模式;其余保留位必须根据实现的兼容性规则进行处理。代码从 9 位开始,当字典达到当前宽度的容量时逐步增加宽度。在块模式下,代码 256 表示 CLEAR:编码器可以输出该代码以丢弃条目,并使用初始字母表重新开始。解码器必须在同一位置重置,然后恢复使用 9 位代码。非块模式数据流没有该重置代码。
代码宽度转换规则属于 .Z 方言的一部分,因此读取器应遵循格式规定的时序,而不是根据下一个代码进行猜测。历史实现对边界情况的处理存在差异;应使用目标 compress 实现进行互操作性测试。
兼容性与操作 #
LZW 专利曾影响 compress 的部署;相关专利已经到期,但旧归档和特定于平台的解码器仍然构成兼容性约束。对于新数据,应使用协议选定的格式。tar 存储文件名和元数据,而压缩器转换的是字节流,因此 .tar.Z 表示使用 .Z 压缩的 tar 归档。
file backup.tar.Z
uncompress -c backup.tar.Z | tar -tvf -
compress -c source.bin > source.bin.Z
zcat source.bin.Z | sha256sum.Z 格式没有类似 gzip 尾部的强制端到端校验和。解码器可能会从截断或损坏的数据流中生成看似合理的字节,因此在转换后应保留源归档,并验证外部摘要或已知文件长度。Gzip 使用 DEFLATE,并在每个成员中记录 CRC-32 以及未压缩大小,因此对于普通文件传输,损坏报告能力更强;但 gzip 和 .Z 不是可互换的数据流。
参考资料 #
- FreeBSD
compress(1)手册,包括.Z选项和块模式。 - T. A. Welch,《A Technique for High-Performance Data Compression》,Computer,1984 年。
- RFC 1952:gzip 文件格式
评论
在 GitHub 上阅读或评论(发表评论需要登录)