zip学习–部分资料汇总

2 Comments

文件格式规范

http://www.pkware.com/documents/casestudies/APPNOTE.TXT

 

网络上的中文翻译

一个 ZIP 文件由三个部分组成:

压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志

1、压缩源文件数据区

    在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下:

       [文件头+ 文件数据 + 数据描述符]
       a、文件头结构

          组成                     长度
       文件头标记                  4 bytes (0×04034b50)
       解压文件所需 pkware 版本    2 bytes
      全局方式位标记              2 bytes
   压缩方式                     2 bytes
最后修改文件时间             2 bytes
最后修改文件日期             2 bytes
CRC-32校验                 4 bytes
压缩后尺寸                   4 bytes
未压缩尺寸                   4 bytes
文件名长度                   2 bytes

      扩展记录长度 2 bytes
文件名                     (不定长度)
扩展字段                    (不定长度)

        b、文件数据

        c、数据描述符

组成     长度
   CRC-32校验                  4 bytes
压缩后尺寸                   4 bytes
未压缩尺寸                   4 bytes

这 个数据描述符只在全局方式位标记的第3位设为1时才存在(见后详解),紧接在压缩数据的最后一个字节后。这个数据描述符只用在不能对输出的 ZIP 文件进行检索时使用。例如:在一个不能检索的驱动器(如:磁带机上)上的 ZIP 文件中。如果是磁盘上的ZIP文件一般没有这个数据描述符。

2、压缩源文件目录区

     在这个数据区中每一条纪录对应在压缩源文件数据区中的一条数据

组成             长度

目录中文件文件头标记    4 bytes (0×02014b50)

压缩使用的 pkware 版本 2 bytes

解压文件所需 pkware 版本 2 bytes

全局方式位标记 2 bytes

压缩方式 2 bytes

最后修改文件时间 2 bytes

最后修改文件日期 2 bytes

CRC-32校验 4 bytes

压缩后尺寸 4 bytes

未压缩尺寸 4 bytes

文件名长度 2 bytes

扩展字段长度 2 bytes

文件注释长度 2 bytes

磁盘开始号 2 bytes

内部文件属性 2 bytes

外部文件属性 4 bytes

局部头部偏移量 4 bytes

文件名 (不定长度)

扩展字段 (不定长度)

文件注释 (不定长度)

     3、压缩源文件目录结束标志

组成           长度

目录结束标记 4 bytes (0×02014b50)

    当前磁盘编号 2 bytes

目录区开始磁盘编号 2 bytes

本磁盘上纪录总数    2 bytes

目录区中纪录总数 2 bytes

目录区尺寸大小 4 bytes

目录区对第一张磁盘的偏移量 4 bytes

ZIP 文件注释长度 2 bytes

ZIP 文件注释 (不定长度)

 

乱谈zip、rar文件格式

http://www.comicer.com/stronghorse/water/software/ZipRar.htm

作者:马健
邮箱:stronghorse@tom.com
主页:http://stronghorse.yeah.net
发布:2006.11.21
最近更新:2006.11.25

目录
一、目录表(TOC)与分卷(Volume)
二、固实(solid)压缩方式
三、安全性
四、开放性
五、结论
声明:本文并非学术论文,所述内容仅为我个人的看法和体会,不具任何权威性,仅供有兴趣的人参考,但是如果您不具有足够的鉴别能力,建议勿看,以免误导。

一、目录表(TOC)与分卷(Volume)

抛开压缩算法不谈,我认为zip、rar在文件格式上最大的差异就在目录表(Table of Contents,TOC):zip有TOC,而rar没有。

TOC这个词其实是从出版界借用过来的,指的就是每一本书正文前面的“目录”,它的作用地球人都知道:如果想快速找到书中某一内容,可以先查TOC,然后按照TOC指明的页码直接翻即可。

在纸质书里TOC是印刷出来的一张表,而在电子文件里则是由结构化数据构成的一张表,它的目的同样是为了快速定位:如果想找文件中的某一内容,可以先查TOC,知道感兴趣的内容在文件的什么位置,直接跳过去就行了。最常见的运用就是avi、rm等多媒体文件:播放的时候经常有人在播放条上点来点去跳着看(即“随机访问”),如果没有TOC,在长达几百兆的文件里来回定位会慢死。

具体到zip文件里,TOC是放在文件尾部的一张表,里面列出了zip包中每一个文件的属性(文件名、长度等)和在zip包中的存放位置。如果需要随机访问zip包中的某一个文件,只需在TOC里找到这个文件的存放位置,直接跳过去即可。

而RAR文件里则没有TOC,在文件头之后所有文件按顺序连续存放。

这种差异造成的结果就是:随机访问时zip比rar快,而顺序访问时rar比zip快。

所谓随机访问,就是前面说过的随机访问压缩包中某个指定的文件。举一个简单的例子:一本反编译或下载到的网页电子书,有大量HTML、图像、css、js,然后打成压缩包。现在要求在不解包的情况下访问其中的页面:可以想象,打开每个HTML页面的时候,它所附带的图像、css、js等文件可能随机分布在整个压缩包里,如果没有TOC,查找每个文件的时候都要从头开始找,将会有多慢。 所以各位可以理解为什么jar包就是标准zip包,而我也只用zip格式保存反编译出来的电子书、漫画、PDG书等一切可能需要随机访问的东西。

所谓顺序访问,就是将整个压缩包从头解到尾。在这方面RAR具有天然的优势。而且为了节省WinRAR列文件的时间,对于单个RAR我一般都直接通过右键菜单解压缩,很少双击压缩包打开再解压。解多个RAR时当然都用BatchUnRar。

由于rar的原作者已经去世,造成这种差异的确切原因我相信已不可考,但我个人猜测可能与DOS时代的备份软件之争有关:在DOS时代,电脑硬盘不像现在这样奢侈,20MB就算很大了。这样的容量用两盒软盘 即可备份,备份成本相对数据本身的价值来说非常低廉。因此在DOS时代,很多公司和机构都制定有定期硬盘备份政策,以免因为人为或非人为的因素 (早期硬盘可没有如今可靠)而造成不可挽回的数据损失。在备份软件方面,虽然微软已经随DOS提供了Backup/Restore工具,但是他们基本不具备数据压缩能力,因此在压缩软件中提供备份功能,就成为DOS时代的一个时尚。由于DOS时代的备份介质多为软盘,因此压缩 软件的备份功能其实就转化成如今很常见的一个功能:分卷压缩功能,即按照软盘容量进行分卷压缩,然后将分卷压缩文件备份(Backup)到软盘,需要的时候再解压,或恢复(Restore)到硬盘。

DOS时代最有名的zip工具是pkzip,出现得比DOS版的RAR早。在分卷压缩时,pkzip按照zip文件规范,将TOC存放在最后,即存储在最后一卷,由此带来如下问题:

1、恢复时,每解压一张盘,都要先将最后一张盘插进去一次,读一次TOC。
2、只要最后一张盘上的TOC坏了,就算其它盘都是好的,也不能正常解压。

这两个缺点,尤其是第一个缺点实在是太臭名昭著了,因此当时出现了非常强烈的改革呼声。在这个关键时刻,DOS版的RAR出现了:不仅压缩率比pkzip高(这点在DOS时代非常重要,毕竟软盘又贵容量又小),而且由于吸取了当时对zip格式的批评,取消了TOC,因此:

1、在恢复分卷压缩的备份文件时,不需要频繁插入带有TOC的分卷,按顺序换盘即可。
2、即使某个分卷损坏,也可以跳过,从完好的分卷再开始解压。

由于这些原因(当然还有其它原因),RAR推出后迅速取得了成功,pkzip在DOS时代就开始流失用户,到Windows时代基本消声匿迹。在Windows时代推出的Winzip,则彻底放弃了分卷压缩功能(zip格式永远的痛?)。 而从我看到的源自WinRAR的UnRAR源代码来看,现在WinRAR的解压思路明显还是把文件按顺序从头解到尾,看来当年备份/恢复工具之争的影响,还真是深远。

二、固实(solid)压缩方式

在压缩算法方面,我觉得rar格式最特色的是固实(solid)压缩方式。WinRAR v3.42的帮助文件中对固实压缩的说明如下:
固实压缩文件是 RAR 的一种特殊压缩方式存储的压缩文件,它把压缩文件中的全部文件都当成一个连续数据流来看待。
这段说明其实揭示了固实压缩格式能够提高压缩比的奥秘:数据压缩的基础是“重复”,例如aaaabbb这个字符串,里面就有重复,如果表示为a4b3,看起来是不是变短了?这就是“数据压缩”。“重复”是一个具有相对意义的概念,在某一范围内看起来没有重复,或重复不多的数据,把范围扩大,说不定就能找到更多重复的数据了,这就是固实压缩的奥秘。

举一个简单的例子:用zip和普通rar压缩一堆jpg文件,很难压下去,但是用固实压缩方式的rar就可以,其原因就在于:jpg文件本身已经是压缩格式了,单个jpg文件里很难再 找到可利用的重复数据,因此不论是用zip还是普通的rar都很难再压缩,因为他们都将需要压缩的文件分隔开来一个一个处理。但是对于固实rar来说,是将 所有需要压缩的jpg文件当作一个整体来压缩,这些jpg之间就存在重复的数据,如他们都有相同的文件头(其中包括各种数据表)等,这就出现了可压缩的空间。从我看到的资料来看,Flash文件也采用了类似的技术对jpg进行压缩:如果在Flash文件中使用了多个jpg文件,它们可以共用一个文件头。
当然天下不会有白吃的午餐,固实压缩方式在提高压缩比的同时,也有一些限制,在WinRAR v3.42帮助文件中的说法是:

固实压缩可增加压缩性能,特别是在添加大量的小文件的时候,但它也有一些重要的不利因素:

  • 对已存在的固实压缩文件更新时较慢;
  • 要从固实的压缩文件解压单个文件时,它之前的文件都需先经过分析。这造成当从固实的压缩文件内取出文件时会比一般压缩文件取出文件慢一些。但是,当从固实的压缩文件解压全部的文件时,解压速度并没有影响。
  • 如果在固实压缩文件中的任何文件损坏了,要从损坏的范围中解压全部的文件是不可能的。因此,如果固实压缩文件是保存在例如软盘等媒介时,推荐你在制作时使用“恢复记录”。

固实压缩的适用场合为:

  • 压缩文件很少更新的时候;
  • 不需要经常从压缩文件中解压一个文件或是部分文件的时候;
  • 压缩效率比压缩速度更为重要的时候。

与前面说的“随机访问”对应,固实压缩的RAR文件可能是世界上最不适合随机访问的:如果需要访问固实RAR包中的某个文件,就要从文件头开始解压,一直解到这个文件。

三、安全性

这里的安全性包含几个方面的含义:文件系统安全性、密码保护安全性和文件数据安全性。

由于制订zip格式规范的时候操作系统本身的文件安全性还没有引起足够的重视,因此zip格式只记录最基本的文件属性,包括只读属性等,没有其它附加的安全属性。

rar格式刚推出的时候,文件系统的安全性只能参照DOS,和zip差不多。但是rar毕竟是一种封闭的格式,想怎么改作者一个人说了就算,因此当Windows中出现NTFS,并且引入扩展的文件系统安全属性时,rar也积极跟进,所以现在应该说rar格式在这方面比zip强 。

在zip和rar格式中均提供了密码保护功能,但是密码保护的安全强度不同。

zip由于格式开放、代码开源,因此zip密码破解软件出现得比较早,也比较多。初期以暴力破解为主,威胁不大,真正对zip密码安全的致命一击是known plain text(已知明文)攻击法:如果知道加密zip文件中某段内容(密文,ciphertext)解密后的真正内容(明文,plain text),就可以反推出zip加密口令。在这种攻击方法的威胁,及某些国家的法律对密码技术的限制下, 著名开源组织zlib宣布永久放弃对加密zip的支持,详见zlib网站上的相关说明(不过在zlib发行的源代码里仔细找找,还是能找到原来的加/解密相关代码)。

记得rar刚推出的时候也和zip一样,虽然不能列出加密文件中的文件内容,但可以列出加密文件中的文件名。后来大概也是被known plain text攻击法吓到了,增加了一个“加密文件名”选项,干脆连加密rar文件里有哪些文件都看不见,让攻击者想猜明文都无从猜起。

rar格式比zip晚推出,在安全方面吸取了足够的教训,因此采用的是美国国家标准与技术局(National Institute of Standard and Technology, NIST)推荐的、目前公认安全程度比较高的AES对称加密算法 ,密钥长度128位。在ASE被攻破以前(NIST认为30年内无法攻破),大家都只能在暴力法上兜圈子,所以密码安全性应该说比zip高。对此WinRAR 3.42的帮助文件是这样描述的:

ZIP 格式使用私有加密算法。 RAR 压缩文件使用更强大的 AES-128 标准加密。如果你需要加密重要的信息,选择 RAR 压缩文件格式会比较好一些。为了确实的安全性,密码长度请最少要 8 个字符。不要使用任何语言的单词作为密码,最好是任意的随机组合字符和数字,并且要注意密码的大小写。请记住,如果你遗失你的密码,你将无法取出加密的文件,就算是 WinRAR 的作者本身也无法解压加密过的文件。

在数据安全性方面,RAR格式本身支持一种特殊的附加信息类型,叫做“恢复记录”。如果RAR文件有恢复记录,在介质物理损坏或其它原因造成数据丢失时,WinRAR可以按照“恢复记录”尝试对数据进行修复。而zip格式无恢复记录,因此在数据安全性方面应该说比RAR弱。

虽然RAR文件本身支持恢复记录,但是在WinRAR里此选项缺省是关闭的,而打开后会导致压缩出来的RAR文件体积增加(增加的百分比与设置有关),可能会令某些人感到不习惯(我就亲眼见到有人在论坛上抱怨为什么压出来的RAR文件会如此庞大),所以这个功能基本上形同虚设。

四、开放性

开放性的对比很明显:zip格式不仅文件格式完全公开,而且有专门的开源组织提供操作源代码,跨平台使用也没有多大限制;rar格式完全保密,作者只提供解压所需源代码,不提供压缩所需源代码 ,跨平台使用有点麻烦。

zip开源组织中,最出名的是zlibInfoZip,二者各有侧重:zlib偏重对内存缓冲区的压缩,因此被png等开源组织用做内部压缩算法,连java的jar程序内核都来自zlib,打出来的jar包自然也是一个标准的zip文件;InfoZip偏重对文件的操作 (包括口令保护),应用似乎不如zlib广泛,但我个人觉得其实它还是满好用的,前提是需要对它的源代码进行一些必要的修改。

png组织的网页中有说到png格式的来历,我觉得也很有意思:做png的一班人,其实原来都是做gif格式的,但是由于Unisys公司开始对gif格式的核心——LZW压缩算法征收专利费,这帮人怒了,干脆提出png格式:大结构方面还是采用分段结构,但是核心压缩算法采用开源的zlib,压缩 效果在多数情况下比gif的LZW更强。由于没有版权限制,在静态图形领域png得到广泛应用,如果不是及时提出动画支持并因此在web上大行其道,我估计gif早就死掉了。

RAR的解压源代码在其官方网站www.rarlab.com上提供,通常比WinRAR的正式版本晚一点,不过据说是直接从WinRAR的源代码中抠出来的,所以兼容性应该没有什么问题。

五、结论

以下观点纯属个人观点,仅供参考,不具有如何指导意义:

  • 如果经常需要对压缩包进行随机访问,应该选zip而不是rar。虽然将下载到的rar重新压缩成zip会麻烦一次,但是以后会减少无数的麻烦。
  • 如果需要分卷压缩(如某些网站对上传文件大小有限制),则只能用rar。事实上,这也是我唯一会使用rar格式的场合,其它时候一律zip没商量。

 

【zlib、gzip、zip的区别】

http://blog.csdn.net/wyingquan/archive/2008/06/14/2547664.aspx

【zlib、gzip、zip的区别】

zlib是一种数据压缩程序库,它的设计目标是处理单纯的数据(而不管数据的来源是什么)。

gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格式),它的设计目标是处理单个的文件。gzip在压缩文件中的数据时使用的就是zlib。为了保存与文件属性有关的信息,gzip需要在压缩文件(*.gz)中保存更多的头信息内容,而zlib不用考虑这一点。但gzip只适用于单个文件,所以我们在UNIX/Linux上经常看到的压缩包后缀都是*.tar.gz或*.tgz,也就是先用tar把多个文件打包成单个文件,再用gzip压缩的结果。

zip是适用于压缩多个文件的格式(相应的工具有PkZip和WinZip等),因此,zip文件还要进一步包含文件目录结构的信息,比gzip的头信息更多。但需要注意,zip格式可采用多种压缩算法,我们常见的zip文件大多不是用zlib的算法压缩的,其压缩数据的格式与gzip大不一样。

Java SDK提供了对上述三种压缩技术的支持:Inflater类和Deflater类直接用zlib库对数据压缩/解压缩,GZIPInputStream类和GZIPOutputStream类提供了对gzip格式的支持,ZipFile、ZipInputStream、ZipOutputStream则用于处理zip格式的文件。

所以,你应当根据你的具体需求,选择不同的压缩技术:如果只需要压缩/解压缩数据,你可以直接用zlib实现,如果需要生成gzip格式的文件或解压其他工具的压缩结果,你就必须用gzip或zip等相关的类来处理了。

【DEFLATE】

DEFLATE 是同时使用了 LZ77 算法与哈夫曼编码的一个无损数据压缩算法。它最初是由 Phil Katz 为他的 PKZIP 归档工具第二版所定义的,后来定义在 RFC1951 规范中。

人们普遍认为 DEFLATE 不受任何专利所制约,并且在 LZW(GIF 文件格式使用)相关的专利失效之前,这种格式除了在ZIP文件格式中得到应用之外也在 gzip 压缩文件以及 PNG 图像文件中得到了应用。

DEFLATE 压缩与解压的源代码可以在自由、通用的压缩库 zlib 上找到。

更高压缩率的 DEFLATE 是 7-zip 所实现的。AdvanceCOMP 也使用这种实现,它可以对 gzip、PNG、MNG 以及 ZIP 文件进行压缩从而得到比 zlib 更小的文件大小。在 Ken Silverman 的 KZIP 与 PNGOUT 中使用了一种更加高效同时要求更多用户输入的 DEFLATE 程序。

【INFLATE】

inflate是GZip, PNG等广泛使用的解压算法,linux也使用inflate对内核进行解压.inflate的解压算法使用的第3种快速解压法的一个子集,它不考虑LONG_CODE,同时把SAME_LENGTH合并到MEDIUM_CODE。而对于规则的SAME_LENGTH编码,比如length和distance编码,inflate则使用额外的base和extra表示。这是因为在构造一般的查找表时,虽然对于SAME_LENGTH前缀可以不构造副表,但我们需要另外一个表格来保存符号的顺序,而这个表格的空间可能更大。但对于length和distance编码,他们的顺序是递增的,所以无需额外的表格来保存符号的顺序。

inflate使用root表示上述的b,查找表的数据结构为code.主表和副同时保存在inflate_state结构中的大数组codes[ENOUGH]中.表的构造函数位于inftrees.c文件的inflate_table中.

【7z】

7z 是一种新的压缩格式,它拥有目前最高的压缩比。

7z 已公开了结构编辑功能,所以它可以支持任何一种新的压缩算法。到目前为止,下列压缩算法已被整合到了 7z 中:

压缩算法  备注 LZMA  LZ77 改良和优化算法后的最新版本 PPMD  基于 Dmitry Shkarin 之上的算法 PPMdH 并加以优化 BCJ  32-位 x86 可执行文件转换程序 BCJ2  32-位 x86 可执行文件转换程序 BZip2  标准 BWT 算法 Deflate  标准 LZ77-based 算法

2 Comments (+add yours?)

  1. qiujinwu456
    三 27, 2010 @ 06:04:53

    诶,,莫有时间来弄这些很底层的东西,只要稍微了解一下就行了。

    回复

  2. Randy
    三 26, 2010 @ 21:46:46

    去看Managing Gigabytes: Compressing and Indexing Documents and Images, Second Edition

    回复

Leave a Reply