今天找压缩算法,看到一段陈年往事

此文章转载自2004.10的《大众软件》,原作者为 广东 GZ


前言--王者归来?
等待足足两年之久,压缩霸主WinZip终于在万众期待下发布了9.0正式版。全世界自然一片沸腾,在世界各大知名下载网站中,WinZip9.0再次带起下载狂潮。然而此时国内并没有王者回归的欢呼,却一致委婉或直接地表达出失望地情绪,而下载更新的用户也寥寥无几,这绝对是一道国内独特的风景,它不禁让人想问,为什么?从各种评测报告看,因为不支持RAR格式,所以兼容性更佳的WinRAR3.30全面超越固步自封的WinZip9.0-- 原来这就是国内用户抵触WinZip9.0的唯一理由。

苍天已死,黄天当立。这是国内舆论草率的结论。之所以说草率,是因为甚至都没有出现反面声音的媒体,这绝对不是一个成熟正常的氛围。正是这种一边倒的跟风导致了大量用户极端的心态,于是牵强附会、人云亦云和以讹传讹的声音充斥其间。这不由得让人陷入深思,事实上,看似压缩工具之争的表面下深藏的是压缩格式之争。RAR格式即将或者己经取代了ZIP格式吗?不能仅仅从两者的技术表现和统计数据去回答这个问题,计算机数据压缩格式的发展历程是非常独特的,它的王者之选带有传奇的历史烙印,并一直持续产生着决定性的影响。要正确解答这个问题就必须去了解有关数据压缩的历史,任何试图避开历史环境而做出的结论都是轻率的。因此请不妨先认识数据压缩的历史本来,再来决定这些压缩工具的前程是非。

LZ算法--ZIP与RAR共祖同源
要讲压缩的历史,就不可不提LZ算法,这是一种有关数据压缩的算法,何为数据压缩?从本质上讲,数据压缩的目的就是要消除信息中的冗余。早在LZ算法出现之前,研究员们从理论上探讨了压缩算法的数学基础及模型基础,同时也在这些基础上研究出了一些编码方法,其中的Shannon-Fano编码和Huffman编码非常有影响力。但这些编码,包括后来发展出的"算术编码",都无法成为理想的编码方法--因为它们无法在编码效率和编码速度上同时满足日益增长的压缩需求。这种情况在LZ算法出现时等到了解决。

Shannon编码
1948年贝尔实验室的Shannon发表的论文《通信的数学理论》中指出,任何信息都存在冗余,冗余大小与信息中每个符号的出现概率或者说不确定性有关。Shannon借鉴了热力学的概念,把信息中排除了冗余后的平均信息量成为信息熵,并给出了计算信息熵的数学表达式。这篇伟大的论文后来被誉为信息论的开山之作,信息熵同时也奠定了所有数据压缩算法的理论基础。利用信息熵公式,人们可以计算出信息编码的极限。不过完备的理论并不等于实用的技术,要将理论变为实践,编码方法是极为重要的一步。1948年,Shannon在提出信息熵理论的同时,事实上也给出了一种简单的编码方法--Shannon编码。1952年,麻省理工学院的R.M.Fano又进一步提出了Fano编码。两者后来被称为Shannon-Fano编码,这种早期的编码方法揭示了变长的编码方法揭示了变长编码的基本规律,也也确实可以取得一定的压缩效果,但离真正实用的压缩算法还相去甚远。

Huffman编码
Huffman编码是第一个真正实用的编码方法,由D.A.Huffman在1952年提出。当时Huffman是麻省理工学院的一名学生,据说为了向老师证明自己可以不参加某门功课的期末考试,他设计了这个看似简单却影响深远的编码方法。Huffman编码效率高,运算速度快,实现方式灵活,从20世纪60年代直到现在,在数据压缩领域得到了广泛的应用。而20世纪80年代初,Huffman编码又出现在CP/M和DOS系统中,即使在今天,在许多知名的压缩工具和压缩算法里(如WinZip、gzip和JPEG),也都有Huffman编码的身影。不过,Huffman编码所得的编码长度只是对信息熵计算结果的一种近似,并不能真正逼近信息熵的极限。Huffman编码影响力很深远,至今还在计算机大专学生必修课程《数据结构》中被提及。

LZ是其发明者J.Ziv和A.Lempel两个犹太人姓氏的缩写。此二人于1977年发表题为《顺序数据压缩的一个通用算法》的论文,论文中描述的算法被后人称为LZ77算法。1978年,二人又发表了该论文的续篇,描述了后来被命名为LZ78的压缩算法。其实LZ系列的算法并不新鲜,其中既没有高深的理论背景,也没有复杂的数学公式。它们只是简单的延续了千百年来人们对字典的追崇和喜好,并用一种极为巧妙的方式将字典技术运用于通用数据压缩领域。简单的说如果你习惯用字典中的页码和行号代替文章中的每个单词的时候,那实际上你已经掌握了LZ系列算法的真谛,因此这类编码算法被统称为Dictionary coders。

在1984年,Terry Welch发表论文描述了他在Sperry研究中心(现在Unisys公司的一部分)的研究成果,也就是后来非常有名的LZW算法。它实质上是LZ78算法的一个变种,但被认为是一个独立的编码算法。LZW继承了LZ77和LZ78压缩效果好、速度快的优点,而且在算法描述上更容易被人们接受,实现也相对简单。而在其后发展出来的各式各样的字典编码算法,基本上都是这三种编码算法的分支或变体。也就是说LZ77、LZ78和LZW是字典编码中最基础的3种编码算法。今天我们熟悉的PKZIP、WinZip、WinRAR、gzip等压缩工具都是LZ系列算法的受益者,甚至连PGP这样的加密文件格式也选择了LZ系列算法作为其数据压缩的标准。

字典式编码不但在压缩效果上大大超过了Huffman编码,而且在实现上,压缩和解压缩的速度也异常惊人。于是LZ系列算法的优越性很快就在数据压缩领域里体现出来,使用LZ系列算法的工具软件数量呈爆炸式增长。UNIX系统上最先出现了使用LZW算法的Compress程序,该程序性能优良,很快成为UNIX世界的压缩程序标准。紧随其后的是MS-DOS环境下的ARC程序,还有像PKARC等仿制品。LZ78和LZW一时间几乎统治了UNIX和DOS两大平台。然而随着时间流逝,事情变得耐人寻味。目前为止占据个人用户计算机的主流压缩工具几乎都采用LZ77变种算法,为什么?

叛逆斗士的胜利--ZIP格式诞生
为什么技术实现上更为优秀的LZ78和LZW没有成为最主流的算法?LZ77与它们有什么不同?答案是--专利权。

相对于LZ77完全没有专利限制来说,LZ78在美国稍稍涉及到一些专利禁止区,而LZW正像上文所说的专利权最终归属于Unisys公司。因此直接应用LZ78的算法可能会带来意想不到的麻烦,而所有使用LZW算法(哪怕是他的变体)的人都要获得Unisys公司的专利许可。这种专利限制是相当广泛的,例如GIF图像格式使用了LZW算法,那么所有开发GIF编码/解码器的人都必须要有LZW专利使用许可,这意味着缴纳大笔的专利费。

在DOS年代由于计算机存储介质容量的微小,个人用户对数据压缩软件的渴望是现在的用户无法想象的。例如在1984年,个人计算机的标配不过是容量360kB的5.25寸软盘而已,如果个人能将数据压缩数倍后存储,不啻于节省了一大笔钱。这种渴望在1988年时达到了顶峰,这正是互联网刚刚形成雏形的年代,网络数据交换开始出现。当时最流行的是使用电话线拨号登录别人在家里搭建的服务平台--BBS系统,当时中国也曾有几十个这样的BBS存在,比如水木清华BBS。这种方式不但可以传递文本信息,也可由用户上传文件到站点的计算机以供其他用户下载。不过由于电话线的接入速度慢的可怜,那时的接入标准仅仅是14.4kbit/s,通过BBS传输稍大一点的文件就叫人万分痛苦。于是数据压缩软件就成为了BBS用户一项必须的工具还记得上文提到1985年SEA公司开发的MS-DOS环境下第一个应用LZW算法的ARC压缩软件吗?它是当时MS-DOS下统治性的压缩软件。从技术角度来说ARC确实不错,但使用了专利LZW算法的ARC当然是标准的商业软件,使用这种软件工作就必须付费。不过当时许多玩家根本买不起ARC软件,顺便说一句题外话,那时大多PC玩家基本都没什么富裕的钱,事实上个人计算机本身的发展就是被穷玩家精打细算所推动。不过个人计算机从诞生之日起就充满了叛逆、自由的精神,这也是推动整个个人计算机世界前行的主要动力。此时一个年轻的程序员出现并试图改变压缩世界,这个人叫Phillip W.Katz(菲利普·卡兹)。

20世纪七八十年代出售软件的方式和现在截然不同,以ARC软件来说,它不仅包括了一份EXE可执行文件,还包括它的C语言源代码。经常混迹于BBS上的菲利普·卡兹同样买不起ARC,于是他自己将ARC的C语言源代码进行复制并用汇编语言重写,并将这个压缩工具称作PKARC,这个程序自然与ARC完全兼容,而且由于使用汇编使得速度较ARC更快.在当时的计算机世界里这是一种很普遍的现象,并没有程序员认为这种行为不对,甚至只要不与自己冲突, 被改写者通常也不在乎.不过这次不太一样,菲利普·卡兹不仅仅是自己和朋友用,而是将这个软件以非强迫性注册的共享软件形式向他人发放,但即使是不注册,一样可以毫无限制地使用下去,大批ARC用户自然也就转而使用菲利普·卡兹的软件.SEA其实不是什么大企业,它只是个3人起家的小公司,当然无法接受这种毁灭性打击.以现在的眼光看来,最初SEA的方式是温和的,它接洽菲利普·卡兹并希望通过授权的方式将PKARC纳入旗下,然而并不认为自己有什么过错的菲利普·卡兹一口拒绝,他不想让PKARC成为商业软件, 他制作这个工具的初衷并不是为了赚钱.最终菲利普·卡兹被SEA以侵犯ARC压缩格式编码算法的罪名告上了法庭,并输掉了官司.叛逆倔强的卡兹在败诉后依然拒绝将PKARC授权给SEA公司,而选择了支付法律费用和停止发放PKARC。

这场官司对菲利普·卡兹的人生观和信念影响巨大,追求自由平等的精神并不意味着盲目和法律对抗,试图劫富济贫的少年侠客行为只能逞一时快意,实质上帮助不了任何人。在官司的进行中,菲利普·卡兹一直在持续开发PKARC的后续产品PKPRC,败诉后菲利普·卡兹决定将PKPRC完全重写。很显然,这次再也不能去触犯任何编码算法的专利权了,从3个基本编码算法来衍生自己的算法是必然的,于是去掉有专利权的LZW和LZ78,剩下的就只有LZ77。也许是被激怒后带来了惊人的动力,只用了几周的时间菲利普·卡兹就创造出一个全新的压缩编码算法,该算法完美地结合LZ77和Huffman编码,也就是后来大名鼎鼎的DEFLATE算法了。新压缩软件被命名为PKZIP,而其文件格式扩展名叫作".zip"。PKZIP可将多个文件压缩到一个文件中,无论压缩比、压缩速度都全面超过了商业软件ARC。菲利普·卡兹将PKZIP作为自由软件免费发放,使其如野火般在全美各大BBS上蔓延开来,用户以几何级数增长,遭受毁灭性打击的SEA公司半年内就无声无息。这段故事最后演变为用自由软件打败商业软件的传奇,菲利普·卡兹更是成为充满幻想的年轻程序员心中十步杀一人的偶像。

然而事情如果仅仅到此为止,那么这也不过是菲利普·卡兹为私人恩怨而快意恩仇的行为,未必能得到后人的真正尊重。不过他做出了一个让所有计算机用户都收益无穷的举动,那就是宣布开放ZIP格式,任何人都可以自由使用ZIP编码算法而不需要缴纳任何专利费用。这个决定最终改变了压缩的世界,使得通用数据无损压缩领域再无法出现垄断的商业巨鳄,真正意义上帮助了每个需要压缩的计算机用户。凭借这个无私的行为,菲利普·卡兹真正成为他想成为的英雄。

群雄逐鹿的结局--WinZip加冕王者
在DOS时代,ZIP格式和它的工具PKZIP并没有成为压缩世界的王者。虽然ZIP格式源于其开放性而在BBS上逐渐成为主流,不过当时的BBS网络环境仍然只属于少数PC玩家。由于CPU运行速度与存储硬件容量的有限,当时个人计算机总是欢迎锱铢必计的压缩软件,因此程序员们也在不懈追求,开发出更快更好的编码算法与压缩工具。1988年到1995年堪称压缩世界的黄金时代,压缩世界处于群雄逐鹿的乱战之中,与PKZIP具有相同影响力的还有LHA(压缩格式为LZH、LHA)和ARJ(压缩格式为ARJ)。

历史遗留格式:LHA
1988年除PKZIP外,另一个重要的压缩工具LHA也诞生了。它的原始名字叫LHArc,由Haruyasu Yoshizaki所开发,同样是免费软件。较之PKZIP,LHA的优势在于压缩率更高,而且跨平台性支持更好,因此成为日本最流行的压缩软件。不过在西方它也同样很受欢迎,大名鼎鼎的id Software就是使用LHA来压缩他们早期游戏的安装文件,也就是DOOM。即使现在LHA已经不再流行,但LHA压缩格式文件仍有不少应用,例如我们经常升级的BIOS文件,AWARD公司使用的就是LHA压缩,而在日本的网站更是随处可见。

历史遗留格式:ARJ
1990年,Robert K.Jung开发出一个新的压缩工具,并将其命名为ARJ(Archiver Robert Jung)。这是一个模仿PKZIP之作,与PKZIP极为相似。不过ARJ确实非常优秀,不仅压缩率高人一等,在功能应用上也明显胜出同类产品一筹。例如它是第一个实现分卷压缩的压缩工具,这对于当时以软盘为主要存储方式的PC来说简直就是雪中送炭。ARJ很快凭借着自己的实力占据一席之地,并逐渐成为DOS下最受欢迎的压缩工具之一。

如果计算机的操作系统一直是DOS,那么压缩工具有可能会三分天下。然而在1995年,改变个人计算机世界的事情出现了,那就是Win95的诞生。没有了DOS系统的艰涩难懂后,人们发现个人计算机并不神秘,它的使用原来可以这么简单。随即PC真正开始普及,普通人成为了主要用户。然而另一方面,大多数从DOS年代过来的程序员高傲地拒绝着Win95,从他们的级数眼光来看,这个动辄崩溃的平台由于底层过于封锁,完全限制了编程的发挥,执行效率与DOS相比也是一塌糊涂。因此Win95发布的最初几年里,并没有出现太多应用软件,程序员们仍然在坚持为DOS编写软件。此时随着计算机硬件的发展,图形网站逐渐代替了文字BBS,普通人不用怎么学习也能轻松上网,大量用户涌入了这个虚拟世界。矛盾自然而然就产生了:大量没有受过训练的Win95用户拿着DOS下的压缩工具不知所措,而程序员们却没有开发Windows平台压缩工具的想法。于是一个原来默默无名压缩软件开始声名鹊起,它就是WinZip。

早在1991年微软发布Win3.0不久,共享软件WinZip1.0就诞生了。虽然它号称是Windows ZIP,但实际上跟Win3.0的本质一样,仍是个外壳程序,它不过是在调用DOS下的工具软件而已。很难了解当时WinZip软件作者的想法,也许只能归于远见卓识,在大多数程序员都在开发自己的压缩编码算法的时候,他选择了使用免费的ZIP编码算法然后做了一个压缩工具外壳。当时DOS才不过发展到5.0版本,放弃一个主要的平台而去做一个附属平台的压缩工具,最主要还是没有自己的编码算法,其前途显然是黯淡的。然而到了1995年,这种做法得到了回报,在Win95发布后它马上就推出了相应版本,是当时为数不多的Windows应用工具。实质上此时WinZip仍然是个外壳工具,它还是通过调用DOS程序来解决问题,不过由于前几年积累下的Windows开发经验,使其图形界面在当时做得近乎完美。甚至后来微软在业界的开发会上宣称,Windows应用程序应该怎么做--很简单,像WinZip那样就行。用户发现WinZip界面是如此精美,操作时如此的亲切友好,完全不用去记什么命令参数,只需要鼠标点几下即可,神秘的压缩原来如此简单,更有趣的是它居然没有一个竞争者,此时的同行还不屑与其竞争。夸张的说,WinZip只用了眨眼的功夫就占据了所有的PC,等到其他压缩工具醒悟过来纷纷开发Windows版本或Windows外壳时,由于缺乏开发经验已经远远落后。等到WinZip推出其真正的Windows应用程序6.x版本时,已尘埃落定,没有自己编码算法的WinZip加冕压缩工具的王者。以后的大多数用户都是通过WinZip认识到ZIP格式,以至于不了解历史的用户甚至以为ZIP就等于winZip,是WinZip的成功导致了ZIP格式的流行,事实上恰好相反。

它来自于江湖--RAR离奇崛起
不妨先来思考一个问题,为什么舆论不指责WinZip9.0不支持WinACE的ACE格式,不指责它不支持WinIMP的IMP格式 ......唯独不支持WinRAR的RAR格式就横加指责呢?答案只能是WinZip不得不支持RAR格式。为什么不得不支持RAR格式呢?答案只能是RAR格式已经成为主流,不支持意味着消亡。这真是一个有趣的推论,2002年时中国的IT媒体还将WinRAR归为非主流压缩软件,而不到两年的时间RAR格式就变成了主流格式,简直就是个奇迹!然而这真的是事实吗?

我们知道ZIP格式成为最主流的原因并不是因为WinZip的出现,而是因为ZIP格式的开放性。ZIP与WinZip之间不过是机缘聚会,即使没有WinZip也必将另外出现类似的"xxZIP"共享软件。ZIP格式的开放从根本上避免了数据压缩世界形成垄断,任何一个消费者总会优先选择免费自由格式的压缩工具,更何况这个免费格式是如此优秀,这使得WinZip之后的任何压缩工具只能先支持ZIP格式站住脚,然后再去推广它不开放编码算法的自有压缩格式。因此最后的结论是不开放的商业压缩格式不可能取代免费ZIP格式成为主流,而RAR同ACE、IMP等一样都是不开放的格式,它也不可能成为主流。这个结论显然会刺激某些人的神经,一定有人会指出事实胜于雄辩,让笔者上网去看看到处的RAR压缩文件。笔者并不否认这是某种事实,不过仍然会坚持RAR不是主流。

在任何一个国外知名的下载王者,如download.com等,都不可能找到RAR压缩文件,或者去国外任何一家知名商业网站,其下载资源提供的也只有ZIP压缩包。是的,甚至再国外比较规范的个人网站上,都只提供ZIP打包的文件下载,而不会有其他类型的压缩文件。国内情况会不一样吗?那么去新浪、搜狐、驱动之家这些大的门户网站或正规的商业网站搜索,同样全部是提供ZIP压缩文件的下载,却根本没有RAR文件。并不是这些网站刻意偏爱ZIP,根本原因还是在于免费。发布ZIP压缩文件并不用缴纳任何费用,而如果发布其他商业压缩格式文件,网站就要向其格式拥有者缴纳专利费用,这种企业所需缴纳的费用不是个人注册费用可以相提并论的。由此带来的疑惑是,在中国确实有许多网站只提供RAR压缩文件的下载,那么他们都甘心交钱替WinRAR宣传吗?同样时不开放算法的商业格式,他们为什么不选择压缩率更高功能更加全面的ACE、IMP等格式呢?

首先笔者不排除这种情况,即可能有特别热爱RAR格式,依法缴费然后再帮着推广的网站,不过可以肯定即使有也为数不多。大多数这样的网站非法发布RAR格式文件,区别仅仅在于自己知道或不知道,不过WinRAR公司难道就坐视不管吗?其实道理很明显,没有比推广压缩格式更容易占据压缩工具市场份额的手段了。2002年WinRAR尚未有中国区代理,不过积极开拓海外市场的WinRAR已经意识到,许多中国网站上也流行着RAR压缩文件,于是一时间突然有许多网站声明,下载资源将由RAR压缩包全部改用ZIP包发布,但在WinRAR中国区代理上任后,短短的几个月这些网站又都恢复发布RAR压缩文件,而且使用RAR格式发布资源的网站日益增多。事实已经清楚,非正规网站提供下载资源的确实都是RAR压缩文件,不过为什么它们都选择RAR而不是其他格式,答案说出来熟悉的朋友马上就会明白--ODAY。

2001到2002年中国的宽带网建设一跃成为世界前列,宽带网的发展使得资源的获取变得极其简单。几乎国内有名的资源站点和论坛都出现在此期间,它们无一例外提供的都是RAR格式资源。那么它们的资源又来自哪里?基本都来自于ODAY,所有宣称RAR格式占据网络主流的人都或刻意或无意地回避了这个事实。ODAY是个完全无影无形的破解组织,但他们发布的资源都有同一个特点,就是统一使用RAR格式打包,如此一来发布这些资源的网站要提供ZIP包下载则必须先解开RAR包,然后再将资源重新压缩为ZIP包,最终选择当然是直接提供RAR压缩包下载了,这就是RAR格式开始流行的根本原因。于是奇怪的事情出现了:免费开放的压缩格式得到所有正规商业公司的支持,而收费非开放的压缩格式却崛起于自有破解的地下组织。一个微妙的形势摆在WinRAR面前,它再流行也始终不会去控告违法发布者,那其实是它生存的根源。一个尖锐的问题也摆在用户面前,在合法的前提下你会选择哪种压缩格式?其实是根本就没有选择。

因此不能否认RAR压缩文件在网络上确实到处可见,但既然它来自于江湖,就注定无法真正成为主流压缩格式。

ZIP的真正危机--AES加密
WinZip9.0究竟带来了什么?根本的变化其实只有一个,那就是支持AES 128位和256位高级加密,事实上这也是WinZip9.0迟到两年的主要原因,而这个特性也许会成为WinZip所面临的最大危机。

上文已经交待,WinZip并没有自己的编码算法,ZIP格式是属于PKZIP的(实属PKWare公司)。一直以来WinZip技术上的发展都紧跟着PKWare亦步亦趋,从而就没有也不可能主动去修改ZIP的编码算法。 WinZip9.0中新加入的Enhanced Deflate算法实际仍属于PKWare公司,并且是开放免费的。不过使用WinZip9.0压缩的ZIP文件,其他支持ZIP格式的压缩工具都能正确解压吗?答案让人遗憾,如果你使用了WinZip9.0的AES加密,那么你只能使用WinZip9.0才能解压。

与成熟的商业压缩格式相比,ZIP格式有一个致命缺陷就是缺乏加解密算法,仅凭其可怜的口令密码保护功能根本无法保障文件的安全。为ZIP格式增加加密算法成为必然之路,然而此时PKWare与WinZip的矛盾终于凸现。2002年,PKWare首先开发了基于证书的安全措施和256位AES加密算法的PKZIP5.0,但随后2003年出现的WinZip9 Beta中采用的256位AES加密算法(但没有证书)却证明无法与之兼容。WinZip9向媒体说明由于PKWare向WinZip保留了算法的技术细节而不能与之兼容,并且表示他们一直期待能够完全兼容,但PKWare并不给予合作而最终导致两者不兼容。PKWare首席技术官Jim Peterson则辩称,基于证书的加密技术目前还正在研制,之所以没有公布是因为还要在其中增加很多功能。WinZip对上述解释表示怀疑,因为除了加密细节没有公布,连证书的细节也不得而知,而事实上在PKZIP5.0 for Windows中这项技术已经使用了一年,PKWare无非是要吃独食,他们违背了自己宣称的ZIP标准开放性。不管事情的真相到底是什么,WinZip为此付出了两年的时间,最终结局仍是两者分道扬镳,各自开发自己的加密算法,而ZIP格式从诞生以来也首次走到了十字路口。

因此AES加密将是一柄双刃剑,也许能为WinZip打开一片商业的天空,也许带来潜伏的危机。这取决于最终应用环境是支持它还是PKWare,抑或是这纷争中崛起的第三者,这是压缩王者的最大危机。

压缩工具之选--合适才是最好的
了解了足够的压缩世界的历史,再回到压缩工具本身来吧。现在的事实是网络上确实存在许多RAR压缩文件,当然使用WinRAR去解压是第一选择,不过是否因为WinRAR也支持ZIP格式就可完全抛弃WinZip?笔者的答案是WinRAR不能完全替代WinZip。即使抛开历史完全从技术上分析,RAR实际上仍处于劣势。

首先来看两者的性能,压缩工具的性能决定于它们的算法。事实上WinZip和WinRAR使用的都是LZ77算法的变体,因此两者基本上不可能出现根本性的性能差距,它们的比较就是看谁在压缩率和工作效率之间取得更佳的平衡性。众所周知RAR的压缩率要略高于ZIP,但这是以牺牲工作效率换取的,这种牺牲值不值得呢?笔者随意做了一个测试,由于太小的文件根本无法察觉,因此测试对象是一个615.6MB的ISO文件,机器配置位P4 1.6A,512MB RAM。结果WinRAR3.30在一般压缩下,使用了30分20秒将文件压缩为607.6MB的RAR文件,而WinZip9.0在一般压缩下,使用了2分40秒将文件压缩为609.2MB的ZIP文件。解压的结果与压缩类似,千分之二的压缩率差距却使用了数十倍的时间,显然ZIP算法的压缩率与工作效率之间的平衡性处理得更好,也就是说性能更优。其实RAR算法在压缩率与工作效率之间的处理也是非常聪明明的,其压缩小文件时损失不易察觉的几秒钟换来总是比ZIP略高一点的压缩率,这给用户留下了极好的印象。

虽然我们证明了ZIP算法的性能更优,不过WinZip不能支持RAR,而WinRAR却能支持ZIP,为什么不保留兼容性更佳的WinRAR?既然RAR是非开放的格式,别人没有它的算法,那么支持解压RAR是如何做到的呢?任何支持RAR格式的压缩工具都带有一个UNRAR.dll文件,这个文件是WinRAR提供的解压库,也就是说其实仍然是WinRAR自己在解压。像这样通过外部调用来支持的格式在WinZip中只有3种,就是上文提到过的ARC、ARJ、LHA,全部是历史遗留。但WinZip显然不会这样去支持RAR格式,在它眼里RAR和ACE、IMP等非公开格式并没有根本上的区别。所以并不是WinZip高傲自大,也不是它固步自封,除非RAR开放算法,否则WinZip是不会调用支持RAR的,替别人推广压缩格式不如将命运掌握在自己手上。再回到兼容性上,实际上查看一下就会发现,WinZip支持超过22种格式,远超过WinRAR支持的12种,就算勉强算上WinZip不支持RAR格式,也只能说两者在这方面不分上下。

由于ZIP格式的开放性所带来的优势也必须考虑。例如微软操作系统从WinMe开始内置支持ZIP格式,ZIP文件被当作一个文件夹操作,别的压缩格式就必须安装压缩工具解压。又如GBA游戏机的模拟器VBA内置支持ZIP,所以压缩为ZIP格式的ROM文件它可以直接读取,别的压缩格式就必须解压回ROM文件。越来越多应用程序都开始内置支持ZIP,此时的ZIP压缩文件相当于透明的源文件。由于ZIP格式的开放性,ZIP文件在网络传输上也具有一些优势,如某些内置ZIP算法的下载工具可分析要下载的ZIP包,可以只下载包内某些文件,这都要归结于ZIP格式的开放性。

以上所有一切都只为说明一件事:ZIP格式仍然是适合个人使用的最佳压缩格式,而RAR是适应现实环境的第二选择压缩格式。因此压缩工作也许会演变为这样的形势:更多的压缩是ZIP文件,而经常解压的是RAR文件。尽管WinRAR也支持ZIP的制作,但程度优先,例如其不支持64位扩展,单个文件都4GB的限制,不支持增强真空算法的压缩,不支持ZIP文件的压缩分卷......制作ZIP文件的最好工具依然是WinZip,这就是为什么WinRAR不能完全替代WinZip。是的,压缩工具的选择应该这样,为了适应环境安装使用WinRAR,为了高效压缩安装使用WinZip。个人建议是,如果压缩工具对你而言主要是解压,极少压缩的话,那么WinRAR确实已够用了:如果要尝试压缩,那么就不要放弃WinZip。

尽管笔者一再表明WinZip不可替代,但实际上对WinRAR也充满好感。这个紧随着WinZip的压缩工具确实是所有模仿者中做得最为出色的,针对于WinZip的弱点作出的技术细节修改也极为有效。如WinZip必须压缩后分卷而WinRAR可以直接分卷压缩,又如WinZip无法管理压缩包内的子目录而WinRAR可以直接显示目录层次......所以即使RAR格式没有那么流行,WinRAR也仍然是最值得推荐安装的压缩工具。文章的最终目的并不是为WinZip与WinRAR打擂台,只是将一些事实的本来面目呈现给人们,而将其后的事情交给他们自己去判断。这本应该是大多数媒体应该做的事情,讲述客观的事实而不是引领读者的情绪,然而国内媒体的浮躁却再次让人失望。

后记
2000年4月14日,年仅37岁的菲利普·卡兹被人发现倒毙在美国威斯康星州密尔沃基的一家汽车旅馆里,据说死因是慢性酒精中毒引起的并发症。被人发现时卡兹的手中仍握着一个烈性酒的酒瓶,在同一个房间里还发现了另外5个空酒瓶。这位天才程序员从未在ZIP身上得到半点好处,坚持信念的结果是潦倒的生活。他为世界贡献了一个伟大的免费软件,更为重要的是他缔造了一种大众化的压缩格式,然而却过早的离开了这个世界。仅仅两年后,PKWare和WinZip为了商业利益开始分道扬镳。用ULTRAEDIT打开任意一个ZIP文件,都可以看到嵌有菲利普·卡兹姓名字头缩写字母PK,每个ZIP文件都将永远记载着菲利普·卡兹,因此菲利普·卡兹和他的ZIP压缩格式也必将得到永生。不知为什么对于菲利普·卡兹的记忆,在笔者脑海中浮现出的是华莱士的那声呐喊:"Free!"

谨以此文向那些无私的天才程序员们致敬。

---------------------------------

另:DEFLATE算法的java实现:
try {
// Encode a String into bytes
String inputString = "blahblahblah??";
byte[] input = inputString.getBytes("UTF-8");

// Compress the bytes
byte[] output = new byte[100];
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.finish();
int compressedDataLength = compresser.deflate(output);

// Decompress the bytes
Inflater decompresser = new Inflater();
decompresser.setInput(output, 0, compressedDataLength);
byte[] result = new byte[100];
int resultLength = decompresser.inflate(result);
decompresser.end();

// Decode the bytes into a String
String outputString = new String(result, 0, resultLength, "UTF-8");
} catch(java.io.UnsupportedEncodingException ex) {
// handle
} catch (java.util.zip.DataFormatException ex) {
// handle
}

你可能感兴趣的:(技术及应用)