我花了几天时间阅读zlib(以及gzip和deflate)RFC,我可以说它们有点垃圾。相当一些细节缺失,所以我打开这个问题。
我试图解析zlib数据,我需要了解有关标题的一些细节。
首先,RFC表示将有2个字节,CMF
和FLG
。
CMF
分为2个4位部分。第一个是CM
,第二个是CINFO
。
CM
的可能值是多少? RFC说8
表示deflate
,而15
是保留的,但剩下的可能值是什么呢?
CINFO
应该总是8,如果我正确理解RFC(如果我错了,请纠正我)。
跳过FLG
和可能的FDICT
,我们转到Compressed data
部分。 RFC的这一部分说:
For compression method 8, the compressed data is stored in the
deflate compressed data format as described in the document
"DEFLATE Compressed Data Format Specification" by L. Peter
Deutsch. (See reference [3] in Chapter 3, below)
这是什么意思?我应该假设CM
总是8吗?如果yes
,为什么整个CM
存在?
最后,我有点困惑。我一直相信zlib可以包装deflate和gzip,但是阅读这个RFC我不能看到gzip压缩数据在这里适合的位置。我有什么遗漏吗?
答案 0 :(得分:4)
CM
的可能值是多少? RFC说8
表示deflate
,而15
是保留的,但剩下的可能值是什么呢?...
我应该假设
CM
总是8吗?如果yes
,为什么整个CM
存在?
CM
可供将来使用并允许其他(非标准)压缩方法:
此版本的zlib规范未指定其他压缩数据格式。(RFC 1950, "ZLIB Compressed Data Format Specification version 3.3")
你不应该假设它始终是8.相反,你应该检查它,如果它不是8,则抛出“不支持”的错误。
另一方面,
CINFO
应该总是8,如果我正确理解RFC(如果我错了请纠正我)。
不,CINFO
的含义取决于CM
。如果CM
为8(唯一有意义的标准化值),则:
CINFO
是LZ77窗口大小的基数2对数,减去8(CINFO=7
表示32K窗口大小)。此版本的规范中不允许CINFO
大于7的值。(RFC 1950, "ZLIB Compressed Data Format Specification version 3.3")
所以实际上CINFO
不能为8。
跳过
FLG
和可能的FDICT
,我们转到Compressed data
部分。 RFC的这一部分说:For compression method 8, the compressed data is stored in the deflate compressed data format as described in the document "DEFLATE Compressed Data Format Specification" by L. Peter Deutsch. (See reference [3] in Chapter 3, below)
这是什么意思?
这意味着DEFLATE编码的详细信息未在此标准中指定,但在ftp://ftp.uu.net/pub/archiving/zip/zlib/的其他地方有所描述。
如果您愿意,DEFLATE有自己的RFC,即RFC 1951, "DEFLATE Compressed Data Format Specification version 1.3"。
最后,我有点困惑。我一直相信zlib可以包装deflate和gzip,但是读取这个RFC我看不到gzip压缩数据在哪里适合。我有什么遗漏的吗?
不,zlib无法包装gzip。 gzip和zlib是deflate数据的不同包装器(如zip格式,PNG格式,PDF格式等)。
Gzip使用DEFLATE:
格式目前使用DEFLATE压缩方法,但可以轻松扩展为使用其他压缩方法。(RFC 1952, "GZIP file format specification version 4.3")
CM = 8
表示“deflate”压缩方法,窗口大小最大为32K。这是gzip和PNG (RFC 1950, "ZLIB Compressed Data Format Specification version 3.3")
如果您发现RFC不清楚或难以理解,请考虑查看zlib实现的源代码。虽然某些实现可能是非标准的,但查看源代码可能会帮助您解决一些疑问。
以下是zlib from zlib.net源代码的摘录,回答了您的一个问题:
#define Z_DEFLATED 8
/* ... */
if (BITS(4) != Z_DEFLATED) {
strm->msg = (char *)"unknown compression method";
state->mode = BAD;
break;
}