gzcompress如何工作?

Joc*_*ung 4 php compression gzip

我想知道为什么我需要在使用gzcompress()之后切断最后4个字符.

这是我的代码:

header("Content-Encoding: gzip");
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$index = $smarty->fetch("design/templates/main.htm") ."\n<!-- Compressed by gzip -->";
$this->content_size = strlen($index);
$this->content_crc = crc32($index);
$index = gzcompress($index, 9);
$index = substr($index, 0, strlen($index) - 4); // Why cut off ??
echo $index;
echo pack('V', $this->content_crc) . pack('V', $this->content_size);
Run Code Online (Sandbox Code Playgroud)

当我没有删除最后4个字符时,源代码如下:

[...]
<!-- Compressed by gzip -->N
Run Code Online (Sandbox Code Playgroud)

当我把它们剪下来时,它上面写着:

[...]
<!-- Compressed by gzip -->
Run Code Online (Sandbox Code Playgroud)

我只能在Chromes Code检查器中看到额外的N(不是在Firefox中而是在IEs源中).但是在代码的末尾会有四个附加字符.

任何人都可以解释我,为什么我需要切掉4个字符?

Gum*_*mbo 7

gzcompress实现具有以下结构ZLIB压缩数据格式:

     0   1
   +---+---+
   |CMF|FLG|   (more-->)
   +---+---+

(if FLG.FDICT set)

     0   1   2   3
   +---+---+---+---+
   |     DICTID    |   (more-->)
   +---+---+---+---+

   +=====================+---+---+---+---+
   |...compressed data...|    ADLER32    |
   +=====================+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到最后四个字节是Adler-32校验和.

与此相反,GZIP文件格式是所谓成员的列表,具有以下结构:

   +---+---+---+---+---+---+---+---+---+---+
   |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
   +---+---+---+---+---+---+---+---+---+---+

(if FLG.FEXTRA set)

   +---+---+=================================+
   | XLEN  |...XLEN bytes of "extra field"...| (more-->)
   +---+---+=================================+

(if FLG.FNAME set)

   +=========================================+
   |...original file name, zero-terminated...| (more-->)
   +=========================================+

(if FLG.FCOMMENT set)

   +===================================+
   |...file comment, zero-terminated...| (more-->)
   +===================================+

(if FLG.FHCRC set)

   +---+---+
   | CRC16 |
   +---+---+

   +=======================+
   |...compressed blocks...| (more-->)
   +=======================+

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |     CRC32     |     ISIZE     |
   +---+---+---+---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)

如您所见,GZIP使用CRC-32校验和进行完整性检查.

所以要分析你的代码:

  • echo "\x1f\x8b\x08\x00\x00\x00\x00\x00"; - 输出以下标题字段:
    • 0x1f 0x8b - ID1和ID2,用于标识数据格式的标识符(这些是固定值)
    • 0x08 - CM,使用的压缩方法; 8表示使用DEFLATE数据压缩格式(RFC 1951)
    • 0x00 - FLG,标志
    • 0x00000000 - MTIME,修改时间
    • XFL(额外标志)和OS(操作系统)字段由DEFLATE数据压缩格式设置
  • echo $index; - 根据DEFLATE数据压缩格式输出压缩数据
  • echo pack('V', $this->content_crc) . pack('V', $this->content_size); - 以二进制形式输出CRC-32校验和和未压缩输入数据的大小