zlib标头是什么样的?


70

在我的项目中,我需要知道zlib标题是什么样的。我听说这很简单,但是找不到zlib标头的任何描述。

例如,它是否包含一个幻数?

Answers:


82

链接到RFC

0   1
+---+---+
|CMF|FLG|
+---+---+

CMF(压缩方法和标志)根据压缩方法,此字节分为4位压缩方法和4位信息字段。

bits 0 to 3  CM     Compression method
bits 4 to 7  CINFO  Compression info

CM(压缩方法)标识文件中使用的压缩方法。CM = 8 表示窗口大小最大为32K的“压缩”压缩方法。这是gzip和PNG以及几乎所有其他方式使用的方法 CM = 15保留。

CINFO(压缩信息)对于CM = 8,CINFO是LZ77窗口大小的以2为底的对数,减去8(CINFO = 7表示32K窗口大小)。在此版本的规范中,不允许CINFO的值大于7。在本规范中,对于不等于8的CM,未定义CINFO。

实际上,这意味着第一个字节几乎总是 78(十六进制)

FLG(FLaGs)此标志字节划分如下:

bits 0 to 4  FCHECK  (check bits for CMF and FLG)
bit  5       FDICT   (preset dictionary)
bits 6 to 7  FLEVEL  (compression level)

FCHECK值必须使CMF和FLG(以MSB顺序存储的16位无符号整数(CMF * 256 + FLG))为31的倍数。

FLEVEL(压缩级别)这些标志可用于特定的压缩方法。“放气”方法(CM = 8)将这些标志设置如下:

        0 - compressor used fastest algorithm
        1 - compressor used fast algorithm
        2 - compressor used default algorithm
        3 - compressor used maximum compression, slowest algorithm

这是一个很好的答案:),以多种方式帮助了我……嘿!漂亮的头像
Ryan

108

zlib魔术头

78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression 

这有助于我弄清楚我要处理的压缩类型。我知道文件已压缩,但是正在搜索一些标头字节,结果出现了。谢谢!
ProVega 2014年

4
当使用Java Inflator(使用ZLIB)时,我看到头值为120,-100。这等于78 9C。备份您上面说的话。
2014年

24

ZLIB / GZIP标头

Level | ZLIB  | GZIP 
  1   | 78 01 | 1F 8B 
  2   | 78 5E | 1F 8B 
  3   | 78 5E | 1F 8B 
  4   | 78 5E | 1F 8B 
  5   | 78 5E | 1F 8B 
  6   | 78 9C | 1F 8B 
  7   | 78 DA | 1F 8B 
  8   | 78 DA | 1F 8B 
  9   | 78 DA | 1F 8B 

Deflate没有通用标头


16

以下是Zlib压缩数据格式。

 +---+---+
 |CMF|FLG| (2 bytes - Defines the compression mode - More details below)
 +---+---+
 +---+---+---+---+
 |     DICTID    | (4 bytes. Present only when FLG.FDICT is set.) - Mostly not set
 +---+---+---+---+
 +=====================+
 |...compressed data...| (variable size of data)
 +=====================+
 +---+---+---+---+
 |     ADLER32   |  (4 bytes of checksum)
 +---+---+---+---+

通常,FLG.FDICT未设置(字典标记)。在这种情况下,DICTID根本就不存在。因此,总的听觉只有2个字节。

没有字典的标头值(CMFFLG)定义如下。

 CMF |  FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression 

ZLIB RFC上的更多内容


6

ZLIB标头(在RFC1950中定义)是一个16位的big-endian值。它包含从最高到最低的以下字段:

  • CINFO (第12-15位)
    以2的幂表示窗口大小,从0(256字节)到7(32768字节)。通常是这样7。不允许更高的值。

  • CM (第8-11位)
    压缩方法。仅8允许放气()。

  • FLEVEL(6-7位)
    大致表示压缩级别,从0(快速/低)到3(慢/高)

  • FDICT (位5)
    指示是否使用预设词典。通常是这样01在技​​术上是允许的,但我不知道定义预设词典的任何Deflate格式。

  • FCHECK(位0-4)
    一个校验和(5位,0.. 31),其计算得出的值是整个值除以31后没有余数。

通常,只有CINFOandFLEVEL字段可以自由更改,并且FCHECK必须根据最终值进行计算。*假设没有预设字典,则其他字段所包含的内容也没有选择,因此总共有32个可能的标头有效。他们来了:

      FLEVEL: 0       1       2       3
CINFO:
     0      08 1D   08 5B   08 99   08 D7
     1      18 19   18 57   18 95   18 D3
     2      28 15   28 53   28 91   28 CF
     3      38 11   38 4F   38 8D   38 CB
     4      48 0D   48 4B   48 89   48 C7
     5      58 09   58 47   58 85   58 C3
     6      68 05   68 43   68 81   68 DE
     7      78 01   78 5E   78 9C   78 DA

CINFO压缩器几乎不会将该字段设置为除7(表示最大32KB窗口)以外的任何其他值,因此,您很可能在野外看到的唯一值是底行中的四个(以开头78)。

*(您可能会怀疑FCHECK-的值是否有少量余地-如果两者都通过校验和,是否可以将其设置为0或31?但是实际上,在这种情况下没有任何有效的标头,因此我们不必为此担心。)


4

但是,这里的所有答案很可能都是正确的-如果您想直接操作ZLib压缩流,并且是通过使用gz_open, gzwrite, gzclose函数产生的-那么在zlib压缩流出现之前,还有10个前导字节头-这些都是由函数gz_open产生的-标头看起来像这样:

    fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
         Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);

并导致以下十六进制转储:1F 8B 08 00 00 00 00 00 00 0B 随后是zlib压缩流。

但是还有尾随的8个字节-它们是uLong-整个文件的crc,uLong-未压缩的文件大小-在流的末尾查找以下字节:

    putLong (s->file, s->crc);
    putLong (s->file, (uLong)(s->in & 0xffffffff));

此处介绍了所有内容:tools.ietf.org/html/rfc1952
Vouze
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.