在前面两篇文章中,这里介绍了URL编码和base64的一些知识点,本文将对网络中另外一个常见的编码方式gzip编码进行介绍。
通过阅读本文将了解到以下几个方面:
- 什么是gzip编码
- gzip和deeflate的关系
- gzip编码在协议中如何使用
- 使用程序实现gzip编码
什么是gzip编码
Gzip是GNUzip缩写,是一种文件格式的定义,具体的定义见这里。很多人对于gzip和deflate会经常混淆,本文将给解释。如图1是gzip格式的RFC文档说明:
图1
可以看到RFC中说gzip是一种数据格式,而deflate被称之为一种方法。实际上在deflate的RFC是这样描述的,这里,如下图2:
图2
所以我觉得我个人觉得把gzip理解成为文件格式,deflate解释成为数据格式(另一种说法是混合压缩算法,详见这里,多种算法的结合,往往要定义新的数据结构),LZ77是最终的压缩算法可能更加通俗易懂一些。就是deflate使用了lZ77算法实现了一种压缩数据格式,然后gzip封装了deflate,包装了一下,并定义了.gz结尾的文件格式。gzip文件格式的定义如图3:
图3
在linux上提供了gzip命令对文件进行压缩和解压,linux上使用gzip压缩的文件通常是.gz后缀文件,代表其为gzip格式文件,压缩结束后会添加对应的文件头和文件尾形成gz格式的文件。对应的命令如下图4:
图4
可以看到使用gzip压缩之后,所占的硬盘空闲显著的减少,这样在网络中也能极大的减少数据的传输。
图5
图5使用hexdump命令查看gz文件的16进制形式,可以看到开始的几个字节和图3 RFC中的定义的文件格式是一致的。1F 8B表示gzip格式文件,08表示使用deflate格式。
gzip编码在协议中如何使用
URL以及base64的主要目的还是在于解决特殊字符传输和显示的问题,而gzip核心是一种压缩实现,他的目的是减少文件的大小,节约空间,提高存储效率。随着网络技术的发展,gzip也开始应用在网络传输领域,用于提高网络传输的效率。如下图6就是在HTTP协议中使用gzip进行传输数据。
图6
可以看到客户端在http request使用Accept-Encoding: gzip, deflate表示客户端支持的文件格式,以及数据格式,算法等。服务器在http response中使用Content-Encoding: gzip表示服务端使用的文件格式。
由于在追踪流的时候使用的是follow tcp,因此payload部分显示的是乱码。wireshark本身内置了对于gzip的解码程序,如果想查看解压缩之后的内容,只要follow http即可,如果是ASCII形式,则会显示出对应的字符串。
为了验证传输的内容是gzip压缩的,需要查看原始的16进制,如图7:
图7
可以看到payload部分是1f 8b开头表示的是gzip格式文件,08表示采用delate数据格式。
使用程序实现gzip编码
由于gzip是一种常见的网络传输行为,因此各种WEB编程语言都有实现gzip的编码和解码,例如Python中使用zlib库解码gzip程序如下:
def decompress_data(data,type='gzip'):
if 'gzip' == type:
return zlib.decompress(data,16+zlib.MAX_WBITS)
if 'deflate' == type:
return zlib.decompress(data)
return
if __name__ == "__main__":
#pcap_path = sys.argv[1]
data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\xcf\x06\x00\x47\xdd\xdc\x79\x02\x00\x00\x00'
#data = '1f8b0800000000000003cbcf060047dddc79020000000'
print(decompress_data(data,'gzip'))
可以看到解压之后的内容为字符ok。除了gzip,deflate等压缩形式,目前也还存在着其他的压缩形式,例如google 推荐的sdch。那如何从pcap中还原这些压缩的内容,解压缩并还原成对应的文件,详见我的专栏《pcap网络数据包处理大全》,这篇文章。
本文为优快云村中少年原创文章,未经允许不得转载,博主链接这里。