引言:UNIX/LINUX下大多数都是用gzip格式来做文件的压缩方案的,而gzip文件损坏的情况也屡见不鲜,常见的有遇到坏扇区、压缩进程io阻塞,或恢复后的压缩文件被破坏等。因近期有做关于gzip文件的修复研究,特分为三个篇章对此成果进行表述,分别为原理篇,方法篇,案例篇。此为第一部分原理篇。

gzip的压缩算法本质上是deflate(zip也几乎都用),这个算法其实是由LZ77算法加上一个变形的哈夫曼编码组成的。大概算法流程是:”原始数据--->LZ77--->哈夫曼 “这三个步骤。因啥夫曼树仍有可能进行压缩,所以,实质上的算法流程是:”原始数据--->LZ77--->(哈夫曼树->CL压缩) “

先来聊聊“原始数据--->LZ77”这一层的思想。LZ77的详细算法见相关文档,本文不做赘述,仅描述涉及本文主题的一些思想。本质上看,LZ77是基于对连续重复的字节片断用指向的方式表示来实现压缩。比如:有句英文叫business is business,为了简化这个句子(注意有空格),我们用business is (12,8)来表示,意思是括号内的数字并非原始数据,而是代表从当前位置向前12个字节,并且连续了8个字节的那段文字。这样一来,文字部分就变得简短了。当然,我们一定会注意到,对于每个句子,要额外有信息表示到底是原始数据,还是指针类的数据。所以,整个压缩后的数据,由三类不同的信息元素组成:本来就是这样的文字、指向的位置,指向的长度,这三个元素即是lz77算法中的literal、distance和length。

给定任何一段字节流,如果使用LZ77算法进行了压缩,就一定会得到一段由literal、distance和length组成的字节流,那要如何区分这三类元素呢?distance和length总是成对出现的,所以,其实是如何区分这2类:1、literal    2、distance与length。通过适当方法区分开这2类成员,就完成了LZ77算法的整个方法。

LZ77完成后,会形成一段较短的字节流。但这还不够,还要经过哈夫曼编码进行二次压缩才能使压缩比更为理想。

同样的原因,对哈夫曼编码原理不做过多解释,仅对涉及本文主题的一些原理进行概要性表述。关于哈夫曼编码,举个例子说明一下:如果有一段字节流(由字节为最小单位组成),这些字节流中每种字节值的出现概率是不相同的,但每个字节都使用了8位进行记录,从概率角度可以知道,这一定是可以再做优化的。哈夫曼就是针对这个思想的优化,简单地说,就如同生成了一个一一对应的映射字典,用一些短的位代替经常频繁出现的字节,用一些长的位代替不常出现的字节,这样,总体上就又进行了一次压缩。(本文转载时请保留完整版权信息:www.sjhf.net 北亚数据恢复中心 张宇 )

当然,如何区分某个位置开始的是短的位还是些长的位呢?其实很简单,只要约定:短位用了的,比他长的就不再用这个短位做前缀即可。比如,如果英文中不想用空格间隔开单词了,只需要这样设计:I如果表示我的意思,那其他所有单词就不可能以I开头。AM如果表示”是”的含义,那既没有以A开头的单词,也没有以AM开头的更长的单词了。以此类推,或许Iamchinese就不用加空格也能间隔开了。

因为LZ77压缩后的数据元素中有literal、distance和length,为了有效区分,deflate算法把把literal和length合起来,使用一颗哈夫曼树。树中编码表述的数值如果小于255,即表示literal;如果等于256,表示本压缩块结束;如果大于256,表示length(需要减254得到);如果是length,再在其后紧跟distance的编码,distance使用单一的哈夫曼树,实现方法见相关文档。

literal、distance和length采用的哈夫曼树本身也是个大的负担,为了进一步压缩空间,deflate又对这两颗哈夫曼树进行了一次压缩,同样的,主体上,也是采用哈夫曼算法,这样,就是第三颗哈夫曼树了。

简单的结构如下图:

按照图中结构可知,一个gzip结构大致如下图所示:

可以看到,每个的压缩包均是独立存在的,包括其本身使用的动态哈夫曼树,也仅存在于其作用域的压缩包内。故而,只要找到每个压缩包的起始位置,如果这个包没被破坏,就可解出其对应内容。

通常而言,因gzip的压缩作业窗口仅32K,所以每个包的大小都不会很大,如果部分包损坏,只要找到下一个包的起始,即可正确解压后续的数据。

如果gzip压缩的是多个文件(并非tar之后再做gzip),此种情况则相对容易。对于gzip而言,文件内包含多个原始文件的,不可以多个文件共用一个压缩包,也就是说如果有一个文件损坏,并不影响其他文件。这种思路容易实现,也可以使用linux下的gzip recover来完成修复。

我们重点要讨论的如果单一文件(如TAR包)gzip后,若其中间损坏,如何正确解压出后面的数据。这个思路如果理解了,gzip recover的算法就非常容易理解了,其算法也似乎有些弱了。

详见下一篇章。

linux打包文件恢复,修复损坏的gz或tar.gz压缩文件之原理篇相关推荐

  1. java csv文件tozip后损坏_教你修复损坏的gz或tar.gz压缩文件

    原标题:教你修复损坏的gz或tar.gz压缩文件 接修复损坏的gzip压缩文件之原理篇,再次引用GZIP结构图: 在上一篇中已知,修复一个损坏的gzip文件的关键环节在于找到下一个正常压缩包的起始点. ...

  2. linux下gz和tar.gz、zip压缩解压

    文章目录 说明 分享 tar.gz 常用命令 gz 常用命令 zip 常用命令 总结 说明 本博客每周五更新一次. 日常数据处理中,经常需要压缩数据文件,减小传输带宽,方便分享和存储,整理gz.tar ...

  3. Linux下gz和tar.gz、与Windows天zip压缩解压

    tar.gz tar.gz是linux下常用文件或文件夹打包和压缩方式,它既支持打包,也支持压缩,linux下应用广泛. 常用命令: 打包文件,不压缩:tar -cvf 压缩文件名.tar 待压缩文件 ...

  4. Java多word文件生成后进行压缩并导出下载后,压缩文件损坏并提示“不可预料的压缩文件末端”和“CRC校验失败”

    Java多word文件生成后进行压缩并导出下载后,压缩文件损坏并提示"不可预料的压缩文件末端"和"CRC校验失败" WinRAR 打开情况: 提示不可预料的压缩 ...

  5. ubuntu 编译源码包 dsc diff.gz orig.tar.gz

    2019独角兽企业重金招聘Python工程师标准>>> 1) 在获取源码包之前,确保在软件源配置文件/etc/apt/sources.list中添加了deb-src项以tree实用程 ...

  6. android rar文件怎么打开方式,android开发如何打开rar压缩文件

    释放双眼,带上耳机,听听看~! 有些文件是以压缩包的形式存在的,在打开之前需要对其进行解压,虽然大多数手机系统都有自己的解压功能,但当压缩包大于4GB时,使用自己的解压功能会导致文件损坏,那么andr ...

  7. ksd文件怎么导入存档_DAY5-step5 Python 示例说明 ZIP 压缩文件

    Python使您可以快速创建zip或者tar压缩文档. 以下命令将压缩整个目录 shutil.make_archive(output_filename, 'zip', dir_name) 以下命令使您 ...

  8. .gz 与.tar.gz解压区别

    FileName.gz使用tar -xvf 无法正常解压,需要使用 gunzip FileName.gz FileName.tar.gz tar -zxvf FileName.tar.gz

  9. tar 追加压缩文件

    tar 追加压缩文件 There is no nutrition in the blog content. After reading it, you will not only suffer fro ...

最新文章

  1. R语言ggplot2可视化分面图、在分面图中的每个直方图中添加均值文本标签、添加均值红色竖线
  2. 初级篇第六期:学习UITableView
  3. error LNK2019: 无法解析的外部符号 public: virtual void * __thiscall
  4. Intellij IDEA 创建Web项目并在Tomcat中部署运行
  5. java 主方法 this_java main 方法怎么创建
  6. 平行四边形的特殊性质
  7. 再写dll 关于declspec(dllexport)和declspec(dllimport)
  8. web_find()函数检查中文字符串失败的处理方法
  9. 【系统】windows2003 至少有一个服务或驱动程序无法加载或错误
  10. 小米跨界成立餐饮公司?其实就是新园区食堂...
  11. 若依前后端分离项目部署最简单的方式(推荐)
  12. js 操作获取和设置cookie
  13. java微信公众号图文消息编辑器,如何使用微信公众号自带的编辑器做出简洁舒适的图文排版...
  14. WeaveSocket框架-Unity太空大战游戏-服务端-1
  15. 便携式禁毒采样器的基础功能
  16. 共享单车在疯狂造车,ofo为什么要玩连接+共享单车模式?
  17. JAVA毕业设计科研成果管理系统设计与实现计算机源码+lw文档+系统+调试部署+数据库
  18. 立创eda学习笔记十四:pcb板画布设置
  19. 管理网络(网络概念)
  20. springBoot(6)---文件上传

热门文章

  1. NIST的安全内容自动化协议(SCAP)以及SCAP中文社区简介
  2. 城市级智能网联示范区情况全扫描(2022版)
  3. linux 中的 ln 命令,Linux ln命令操作指南
  4. 软件项目管理–进度计划
  5. MQ命令学习总结大全MQ常用命令
  6. 量化选股策略搭建(一)(股票数据获取)
  7. 【kafka】解决kafka-tool连接上kafka,brokers和topics不显示问题
  8. Qt5开发从入门到精通——第六篇一节( 图像与图片——位置相关函数 )
  9. IDEA提交不显示Git文件呈现红色
  10. python编程认证找工作时有什么作用?