deflate及gzip格式说明

  前段时间公司的web服务器需要增加代理的gz解压功能。刚好手里有一些基础库,试着写了gz的解码函数。
开始以为很简单,后面读了不少相关的文档才发觉还是比较复杂的,花了不少时间才理清楚。
本文就对gz文件格式作一个完整的描述,因为复杂的部分主要是deflate(rfc1951)格式包的实现,所以本文也可以作为
deflate格式的参考简要说明。

为了本文理解上的准确性和rfc1951的标准的一致性,
定义如下的一些术语。

1, 符号 指输入数据的最小分隔单位,一般指0-255的字符。
2, 回退距离(backward distance) 指LZ77往后回退的距离大小,大小从1开始。
3, 匹配长度(length) 指LZ77中符号串在和字典窗口中相等的最长大小。
4, 匹配对 指<匹配长度, 回退距离>的lZ77的记录对,LZ77算法中匹配结果要么是一个匹配中要么是一个字符。
5, 编码表 指符号和编码值(可以是固定值,也可以是huffman编码)的一一对应表

首先,deflate文件的压缩原理说明一下:

deflate使用了lz77的字典压缩和huffman压缩两种方式,扩展位编码及长度压缩内容还使用了类似游程编码的处理方法。
lz77压缩通过查找字典窗口字符串使用匹配对或单个字符记录。
然后使用huffman字符对字符或匹配对进行编码。

具体的huffman及lz77编码方法网上有比较多的参考教程。

deflate格式中字典窗口大小固定为32k, 最长匹配大小为258, 最小匹配距离为3。

其它需要的细化的地方我这再作说明。

实现了上述算法之后,便发现huffman压缩后的编码数据,如何保存编码表才是最主要的工作。
rfc1951的deflate实质上是定义了一种LZ77和huffman编码的保存方案。

下面先说明deflate的字符存储方式(这一部分可参考rfc1951相关部分)。

A, 基本的字节存储方案
deflate格式对于编码的保存采用字节为单位,从左到右依次为第0字节,第1字节...。
  对于一个字节的字节内容deflate的存储方案有两种,一种可以称为数值型,另一种称作编码型。
  对于编码型(包括huffman码和固定的编码)采用从低位到高位的填充方式,对于数值型则使用由高位到低位的方式。
  对于小端机器,可认为编码型存储值和内存二进制值相反,数值编码值和内存二进制值一致。
  
B, 块存储方案
  deflate以流块为基本单位,所有的编码后的数据最后以块存储下来,块中的字节则按A中定义方式进行存储。
  每一个块以三位的编码头开始
  其中第一位指示是否为最后一个块(1表示为最后一块),后两位分别为二进制数值(注意是数值)表示块类型
    00表示非压缩块(简写为ncm(noncompression mode))   无数据压缩
    01表示固定编码压缩块(简写为fcm)                  固定编码表的压缩,数据中无需加入编码表
    10表示带有编码表的块(简写为dcm)                  huffman编码表压缩,数据中含有huffman编码表信息

ncm,fcm,dcm格式块头分别如下(其中第一位(图示第三位)1表示是最后一块:

 +---+---+---+ 
 | 0    0   0/1  
 +---+---+---+ 

+---+---+----+ 
 | 0    1   0/1  
 +---+---+---+   

 +---+---+---+ 
 | 1    0   0/1  
 +---+---+---+ 

   
 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值