代码之家  ›  专栏  ›  技术社区  ›  JochenJung

gzcompress是如何工作的?

  •  4
  • JochenJung  · 技术社区  · 14 年前

    我想知道为什么在使用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);
    

    当我不剪切最后4个字符时,源代码的结尾是:

    [...]
    <!-- Compressed by gzip -->N
    

    [...]
    <!-- Compressed by gzip -->
    

    有人能解释我为什么要砍掉4个字符吗?

    2 回复  |  直到 14 年前
        1
  •  7
  •   Gumbo    14 年前

    gzcompress 实现 ZLIB compressed data format 这是最重要的 following structure :

         0   1
       +---+---+
       |CMF|FLG|   (more-->)
       +---+---+
    
    (if FLG.FDICT set)
    
         0   1   2   3
       +---+---+---+---+
       |     DICTID    |   (more-->)
       +---+---+---+---+
    
       +=====================+---+---+---+---+
       |...compressed data...|    ADLER32    |
       +=====================+---+---+---+---+
    

    这里你看到最后四个字节是一个 Adler-32 checksum .

    与之相反的是 GZIP file format

       +---+---+---+---+---+---+---+---+---+---+
       |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     |
       +---+---+---+---+---+---+---+---+
    

    如您所见,GZIP使用 CRC-32 checksum 进行完整性检查。

    所以要分析代码:

    • echo "\x1f\x8b\x08\x00\x00\x00\x00\x00"; 显示以下标题字段:
    • echo $index; 根据DEFLATE数据压缩格式输出压缩数据
    • echo pack('V', $this->content_crc) . pack('V', $this->content_size);
        2
  •  2
  •   nos    14 年前

    gzcompress生成此处描述的输出 RFC1950 ,最后4个字节是adler32校验和。这是“deflate”编码,所以您应该只设置“Content encoding:deflate”,而不操纵任何内容。

    gzencode() ,它使用 gzip format