个人管理功能

在CSDN Blog撰写技术文章,即有机会入选CSDN技术中心,现在就去免费注册!已注册用户,点击登录

搜索
热门标签
专题历史

有人说SOA是一种IT策略,有人说SOA是一种架构理念,还有人说SOA是一种服务。SOA到底是什么?它将带来什么?软件产业的变革亦或是新的机遇下的挑战?业界权威专家带领我们一起去深究,去探索。BEA三位重量级专家与您共同探讨SOA

随着WPF/E更名为正式名称Silverlight,以及Silverlight 1.1 Alpha 版本的发布,答案变得清晰,而且令人兴奋! - 一个跨操作系统,跨浏览器的Web应用平台出现了。Silverlight 这样一个4.5MB的浏览器插件(1.1 Alpha文件)是如何做到的这些的?周岳: SilverLight-Web应用的一道强光

中国移动用户数量在大踏步地发展与增长,根据产业部的数据,仅三月就新增了670万户。预估计6月份之后,中国很快将迎来第五亿手机用户(平均不到3人拥有一台手机)而J2ME做为最重要的手机跨平台技术,凭借Java平台以其良好的开放性和支持能力,得到了众多手机厂商的支持。对众多开发者来说,J2ME程序易于移植,轻松实现“一次编写,到处运行”。J2ME系列开发专题,将带你从最基本的工具安装,环境配置开始,进入移动应用开发的世界。
 
CSDN移动开发系列之-“J2ME开发实训”

7月31日-8月1日,即将在上海召开甲骨文全球大会•亚太地区会议同期举行的甲骨文开发者大会,这是一项付费参加的面向开发人员的活动。在甲骨文开发者大会期间,您将听到世界一流的专家讲述如何使用Java、.NET、XML和PL/SQL以及Ajax、PHP、Spring、Groovy on Rails等流行技术来简化开发过程。在为期两天的甲骨文开发者大会中,您将能够提高自身的开发技能,扩充知识,参加几十场由专家主持的深入细致的技术讲座并在专家的辅导下进行上机操作、了解高级技能和获得详细指导。在甲骨文开发者大会期间,您有机会直接向业界一流的技术专家和开发人员请教。欢迎参加甲骨文全球大会·2007·亚太地区开发者大会

2007年6月29日,自由软件基金会宣布,其创始人Richard Stallman将在GNU的网站上,在本周太平洋时间星期五上午9点通过视频发布GPLv3。本来,GPL并不是所有开源组织所认可的协议。其从出现以来一直存在争议,GPL被认为是一种“病毒式”的协议,BSD的fans和老牌Unix黑客们认为,他们编写Unix的年头都比GPL声明要长得多,他们更愿意采用比GPL更加的自由的BSD协议。今天,开源社区中有70%左右的项目采用了GPL。很多在开源社区的老牌黑客们认为,Richard Stallman所鼓吹开源软件的言行与当年卡尔·马克思号召产业无产阶级反抗工作的努力如出一辙。在GPLv3的第三版修订案发布时,开源软件团体中的许多成员都反对这种协议。尤其是Linux的核心开发小组,其中29个高级架构师有28个反对这个协议。Linus Torvalds称这个协议有“宗教性质”,并公开反对。而整个软件行业特别是开源社区对GPLv3的争论也愈演愈烈。GPLv3:大教堂和集市的新一轮对抗

2007年7月14日由CSDN与ThoughtWorks联合主办的第二届“敏捷中国”技术大会在北京丽亭华苑酒店召开,多位开源社区和ThoughtWorks公司的技术领袖即将带来精彩的演讲。本次“敏捷中国”技术大会集中展现塑造敏捷企业所需的方方面面:业界领先的敏捷项目管理工具;极大提升软件开发效率的新语言和新框架;数据库领域的敏捷实践;全方位的敏捷项目管理指导;还有身临其境的亲身体验。来自开源社区和ThoughtWorks公司的技术领导者们将带领听众全面感受敏捷企业。“敏捷中国大会”现场直击

从2004年起,在每年的夏季,CSDN都会举办面向中国程序员的大型网上调查活动。这是中国样本最丰富的开发者社区调查,持续、全面和深入地反映了中国开发者社群自身状况、各项技术、工具、产品的使用状况和发展趋势,是完整、准确地了解中国开发者市场的重要参考资料。本次调查覆盖基础信息、.NET、Java、C/C++、Web开发、数据库应用开发、软件工程及项目管理、移动及嵌入式开发、开放源代码、企业信息化等10个领域。还有惊喜大奖等着你哦,赶快进入吧! 2007中国软件开发者大调查正式启动

推荐作者
  • 大宝大宝

    时间如流水,知惜方成功。

  • SkymanSkyman

    江苏人氏,梅兰芳之老乡。现游学渝州之最...

  • ralph623ralph623

新进作者
  • 冲 s冲 s

  • 小鱼小鱼

  • 棱角棱角

    多年J2EE构架设计与开发经验,专注于企业信息系统建设,精通Java设计模式,并能熟练的运用到企业开发中。 精通Struts与Spring框架。数据库方面精通Oracle数据库,从事过数据库方面的开发以及oracle优化方面的工作。

最新技术图书推荐
gzip压缩算法

发表日期:2007-6-29
更新日期:2007-6-29
作者文章阅读次数:12239

源自:我就喜欢 (个人网站) 标签:c/c++

您认为本文应该得        共有17人参与打分打印|收藏|讨论|投诉

gzip压缩算法

 

如果你有时间的话,我建议你先不要看下面的内容,自己尝试通过读gzip源码,来了解它的压缩解压缩是如何实现的,这将会是一个非常有趣的智力游戏,千万不要错过。当一个又一个的谜被解开时,那感觉就像唐伯虎同志所说的,慷慨然诺杯酒中。(小唐的诗,除了另一个倒霉蛋曹雪芹外,好像不太被人提。)

   1 gzip所使用压缩算法的基本原理

   gzip 对于要压缩的文件,首先使用lz77算法进行压缩,对得到的结果再使用huffman编码的方法进行压缩。所以我们分别对lz77huffman编码的原理进行说明。

   1.1 ... 1.2 ...

   2 gzip压缩算法实现方法

   2.1 LZ77算法的gzip实现

  首先,gzip 从要压缩的文件中读入64KB的内容到一个叫window的缓冲区中。为了简单起见,我们以32KB以下文件的压缩为例做说明。对于我们这里使用32KB以下文件,gzip将整个文件读入到window缓冲区中。然后使用一个叫strstart的变量在window数组中,从0开始一直向后移动。strstart在每一个位置上,都在它之前的区域中,寻找和当前strstart开始的串的头3个字节匹配的串,并试图从这些匹配串中找到最长的匹配串。

  如果当前的strstart开始的串,可以找到最少为3个字节的匹配串的话,当前的strstart开始的匹配长度那么长的串,将会被一个<匹配长度,到匹配串开头的距离>对替换。

  如果当前的strstart开始的串,找不到任何的最少为3个字节的匹配串的话,那么当前strstart的所在字节将不作改动。

  为了区分是一个<匹配长度,到匹配串开头的距离>对,还是一个没有被改动的字节,还需要为每一个没有被改动的字节或者<匹配长度,到匹配串开头的距离>对,另外再占用一
  位,来进行区分。这位如果为1,表示是一个<匹配长度,到匹配串开头的距离>对,这位如果为0,表示是一个没有被改动的字节。

  现在来说明一下,为什么最小匹配为3个字节。这是由于,gzip 中,<匹配长度,到匹配串开头的距离>对中,"匹配长度"的范围为3-258,也就是256种可能值,需要8bit来保存。"到匹配串开头的距离"的范围为0-32K,需要15bit来保存。所以一个<匹配长度,到匹配串开头的距离>对需要23位,差一位3个字节。如果匹配串小于3个字节的话,使用<匹配长度,到匹配串开头的距离>对进行替换,不但没有压缩,反而还会增大。所以保存<匹配长度,到匹配串开头的距离>对所需要的位数,决定了最小匹配长度至少要为3个字节。

  下面我们就来介绍gzip如何实现寻找当前strstart开始的串的最长匹配串。

  如果每次为当前串寻找匹配串时,都要和之前的每个串的至少3个字节进行比较的话,那么比较量将是非常非常大的。为了提高比较速度,gzip使用了哈希表。这是gzip实现LZ77的关键。这个哈希表是一个叫head的数组(后面我们将看到为什么这个缓冲区叫head)。gzipwindows中的每个串,使用串的头三个字节,也就是strstart,strstart 1,strstart 2,用一个设计好的哈希函数来进行计算,得到一个插入位置ins_h。也就是用串的头三个字节来确定一个插入位置。然后把串的位置,也就是 strstart的值,保存在head数组的第ins_h项中。我们马上就可以看到为什么要这样做。head数组在没有插入任何值时,全部为0
当某处的当前串的三个字节确定了一个ins_h,并把当时当前串的位置也就是当时的strstart保存在了head[ins_h]中。之后另一处,当另一处的当前串的头三个字节,再为那三个字节时,再使用那个哈希函数来计算,由于是同样的三个字节,同样的哈希函数,得到的ins_h必然和前面得到的ins_h是相同的。于是就会发现head[ins_h]不为0。这就说明了,有一个头三个字节和自己相同的串把自己的位置保存在了这里,现在head[ins_h]中保存的值,也就是那个串的开始位置,我们就可以找到那个串,那个串至少前3个字节和当前串的前3个字节相同(稍后我们就可以看到这种说法不准确,这里是为了说明方便),我们可以找到那个串,做进一步比较,看到底能有多长的匹配。

  我们现在来说明一下,相同的三个字节,通过哈希函数得到的ins_h必然是相同的。而不同的三个字节,通过哈希函数有没有可能得到同一个ins_h,我没有对这个哈希函数做研究,并不清楚,不过一般的哈希函数都是这样的,所以极大可能这里的也会是这种情况,即不同的三个字节,通过哈希函数有可能得到同一个ins_h,不过这并不要紧,我们发现有可能是匹配串之后,还会进行串的比较。

  一个文件中,可能有很多个串的头三个字节都是相同的,也就是说他们计算得到的ins_h都是相同的,如何能保证找到他们中的每一个串呢?gzip使用一个链把他们链在一起。gzip每次把当前串的位置插入head的当前串头三个字节算出的ins_h处时,都会首先把原来的head[ins_h]的值,保存到一个叫prev的数组中,保存的位置就在现在的strstart处。这样当以后某处的当前串计算出ins_h,发现head[ins_h]不空时,就可以到prev[ head[ins_h] ]中找到更前一个的头三个字节相同的串的位置。对此我们举例说明。

  例,串
   0abcdabceabcfabcg
   ^^^^^^^^^^^^^^^^^
   01234567890123456

  整个串被压缩程序处理之后。

  abc算出ins_h
  这时的head[ins_h]中为 13,"abcg"的开始位置。
  这时prev[13]中为 9,即"abcfabcg"的开始位置。
  这时prev[9]中为 5,即"abceabcfabcg"的开始位置。
  这时prev[5]中为 1,即"abcdabceabcfabcg"的开始位置。
  这时prev[1]中为 0

  我们看到所有头三个字母为abc的串,被链在了一起,从head可以一直找下去,直到找到0

  现在我们也就知道了,三个字节通过哈希函数计算得到同一ins_h的所有的串被链在了一起,head[ins_h]为链头,prev数组中放着的更早的串。这也就是headprev名称的由
  来。

   gzip寻找匹配串的另外一个值得注意的实现是,延迟匹配。会进行两次尝试。比如当前串为str,那么str发生匹配以后,并不发生压缩,还会对str 1串进行匹配,然后看哪种
  匹配效果好。

  例子 ...
从这个例子中我们就看到了做另外一次尝试的原因。如果碰到的一个匹配就使用了的话,可能错过更长匹配的机会。现在做两次会有所改善。

   ...

   2.2 问题讨论

  我在这里对gzip压缩算法做出了一些说明,是希望可以和对gzip或者压缩解压缩感兴趣的朋友进行交流。
  我对gzip的了解要比这里说的更多一些,也有更多的例子。如果哪位朋友愿意对下面的问题进行研究,以及其他压缩解压缩的问题进行研究,来这里http://jiurl.cosoft.org.cn/forum/ 和我交流的话,我也愿意就我知道的内容进行更多的说明。

  下面是几个问题

  这种匹配算法,即用3个字节(最小匹配)来计算一个整数,是否比用串比较来得高效,高效到什么程度。

  哈希函数的讨论。不同的三个字节,是否可能得到同一个ins_hins_h和计算它的三个字节的关系。

  几次延迟尝试比较好?

  用延迟,两次尝试是否对压缩率的改善是非常有限的?

  影响lz77压缩率的因素。

  压缩的极限。

   2.3 ...

   3 gzip源码分析

   main() 中调用函数 treat_file()
   treat_file() 中打开文件,调用函数 zip()。注意这里的 work 的用法,这是一个函数指针。
   zip() 中输出gzip文件格式的头,调用 bi_initct_initlm_init
  其中在lm_init中将 head 初始化清0。初始化strstart0。从文件中读入64KB的内容到window缓冲区中。
  由于计算strstart=0时的ins_h,需要0,1,2这三个字节和哈希函数发生关系,所以在lm_init中,预读0,1两个字节,并和哈希函数发生关系。

  然后lm_init调用 deflate()
   deflate() gzipLZ77的实现主要deflate()中。
 

您认为本文应该得        共有17人参与打分打印|收藏|讨论|投诉

暂无图片

相信自己

评论

CSDN技术中心团队官方Blog:http://blog.csdn.net/techcenter/,反馈邮箱:techcenter at csdn.net (注意:请把 at 换成@)


网站简介广告服务网站地图帮助联系方式诚聘英才English问题报告

北京百联美达美数码科技有限公司  版权所有  京 ICP 证 020026 号

Copyright © 2000-2006, CSDN.NET, All Rights Reserved