轻识Logo
目录

    LZ77压缩算法原理剖析

    点击上方“君子黎”,选择“置顶/星标公众号

    干货福利,第一时间送达!

    1. 数据压缩

    数据压缩(Data Compression),简称为压缩,通常也被称为编码(coding)。它是信息论的一个分支,其主要目的是使要传输的数据量尽量最小化。从根本上讲,它在保证能够包含原有相同信息的前提下,使用比原始表示更少的位来对信息进行重新编码。它通过对数据进行编码、重组或修改以减少其大小的一个过程。

    数据压缩在数据存储和数据传输领域有着重要的应用。尤其是在Internet高速发展的今天,文件大小和网络传输速度之间的微妙关系变得更加明显。越来越多的企业和应用需要存储大量的数据文件,同时网络交互、通信传输的数据报文也愈加频繁。更大的数据和带宽意味着需要更高的成本与代价,这无疑与人们追求更高利益化的理念相违背。而通过压缩要存储或传输的数据可以极大地降低存储或通讯成本。对将要发送的数据压缩后,体积变小了,随之而来的是增加了通信信道的容量;而在数据变小之后,相同容量的存储介质间接地可以存储更多的数据量。同时,更小的数据,通过利用 存储层次结构 规则,可以将其放在计层次更高、速度更快的存储层级,从而减少系统I/O通道的负载与压力。

    2. 压缩算法

    尽管压缩算法类型十分繁多,但是从本质上而言,可以归纳为两大类,分别是:无损压缩Lossless Compression)和有损压缩Lossy Compression)。无损压缩算法可以反转以恢复到原始数据,所以它是精确的;而有损算法在反转时候会丢失部分细节或引入一些小错误,所以它不是精确的。

    2.1 无损压缩

    无损压缩算法的基本原理是,对于任何一个非随机文件都将包含重复的信息,而这些信息是可以使用统计建模技术进行压缩,从而确定字符或短语出现的概念进行压缩。然后这些统计模型可用于根据特定字符或短语出现的概率生成代码,并将最短的代码分配给最常见的数据,从而使大量文本中大量冗余的数据被移除。这些技术包括熵编码、游标编码和字典进行压缩。

    常用的无损压缩算法程序有:Zip(使用于Windows系统上)、gzip(工作于类UNIX系统上)等。

    2.2 有损压缩

    有损压缩算法通常通过删除需要大量数据以完全保真度的小细节来减少文件大小。由于该算法删除了许多必要的数据,所以是不能恢复到原始文件的,显然,它实现了非常高的压缩比。最常用于有损压缩算法的场景是图像和音视频数据。

    3. LZ算法

    LZ算法是由Abraham Lempel和Jacob Ziv于1977年发明的算法,因此,该LZ算法也称为LZ77算法(或LZ1)。此算法是第一个使用字典压缩数据的算法。更具体点地说,LZ77算法使用了一个动态字典(Dynamic Dictionary),通常也称为“滑动窗口(Sliding Window)。” 在第二年中,即1978年, Abraham Lempel和Jacob Ziv在基于LZ77算法的基础上,发布了LZ78算法(也称为LZ2),该算法同样使用了字典,但是与LZ77不同的是,LZ78算法取消了动态字典生成;反之,它是根据解析输入数据而生成静态字典。

    LZ算法是一种无损压缩算法。在LZ77和LZ78的基础上,衍生出了许多的无损压缩算法,然而许多算法自面世以来,没隔多久时间就消失了,只有少数的算法得到一直延续到今天且在广泛使用。如下图所示,该图详细地描述了无损压缩算法的层次结构,以及分别在LZ77和LZ78算法版本上所衍生出来的其他算法版本。

    从图中可以看到基于LZ77的算法变体远多于LZ78。这是因为从LZ78上变体出来的LZW算法申请了专利,并开始起诉提供该算法的软件服务商,基于专利保护的缘故,导致该算法的衍生版本不如LZ77多。

    3.1 LZ算法的原理

    当使用LZ算法来对一个符号序列进行压缩时候,它采用如下的示意结构。

    该结构共包含了2个部分,分别是:查找缓冲区(Search buffer),也称字典(所谓字典,就是已编码好的部分)。先行缓冲区(Look ahead buffer),包括即将进行编码序列的一部分。这两个部分组成了这个所谓的“滑动窗口(Sliding Window)。”

    由于缓冲区具有固定的长度,所以,当算法(编码器)在运行时候,它看起来像在文件中“滑动”,所以这个缓冲区被称为“滑动窗口”。而该技术也被称为“滑动窗口技术”。

    查找缓冲区和先行缓冲区都有自己的固定大小,比如上图中,其查找缓冲区大小是3字节,而先行缓冲区是2字节。当然,实际中肯定比这个大许多,这里只是为了方便举例说明。对于LZ算法,滑动窗口的典型大小是4096字节。PostgreSQL数据库中的TOAST技术,也采用了LZ无损压缩算法,其窗口大小也是4096字节。

    //滑动窗口的固定大小 4096字节
    #define PGLZ_HISTORY_SIZE  4096

    3.2  LZ编码过程

    LZ压缩算法使用一个三元组<o, l, c>来对字符串序列进行编码。其中o是offset(偏移量)的缩写,l是length(长度)的缩写,而c则是代表先行缓冲区中位于匹配项之后的字符(character)。也有的文献资料称之为码字(Code Word)。

    现在来详细说明一个三元组<o, l, c>中这几个数字对应的实际含义。这里待编码的字符串序列是“HELLOWORLD”。假定LZ窗口大小是5字节,其中查找缓冲区是3字节,而先行缓冲区为2字节。由于窗口大小是固定的,所以同一时刻(当然,一开始时候,查找缓冲区没有字符),查找缓冲区中最多有3个字节数据,先行缓冲区最多容纳2字节数据。

    假如现在已经对字符‘H’、'E'、'L'、'L'、'O'、'W'这6字符编码完成,其中'L'、'O'、'W'字符位于查找缓冲区中,而先行缓冲区中的字符是'O'、'R'。如下图所示:

    编码器将会通过“查找指针”在查找缓冲区中不断移动(移动方向如上图黑色箭头所示),来判断是否有字符和先行缓冲区中的(第一个)待编码字符相同。这里先行缓冲区中的待编码字符是‘O’。通过判断可知,在查找缓冲区中的第2个位置处有一个字符‘O’和先行缓冲区中的第一个符号相同,该(查找)指针与先行缓冲区的距离称为“偏移量(offset)”,这里偏移量是2。

    此时,LZ编码器会继续查看并判断查找缓冲区中该“查找指针”位置之后的字符,是否与先行缓冲区中第一个字符之后的字符连续相匹配。在查找缓冲区中与先行缓冲区中连续相匹配的字符的数量,我们称之为“匹配长度”。从上图可以看到位于查找缓冲区中的查找指针后面的一个字符是‘W’,而先行缓冲区中第一个待编码字符之后的字符是‘R’,不相匹配。所以这里的匹配长度length等于1。

    先行缓冲区中匹配字符之后的第一个字符是‘R’,所以可以得到一个三元组:<2, 1, C(R)>。待字符‘O’编码好之后,滑动窗口移动一个字符(字节)。此时的查找缓冲区与先行缓冲区中的内容如下图所示:

    LZ编码器继续对先行缓冲区中的字符‘R’进行编码,重复上面的逻辑判断过程。首先在查找缓冲区(Search Buffer)中通过移动查找指针,判断是否有字符和先行缓冲区中的第一个字符(待编码)相等,若有,则继续判断是否有连续的字符和先行缓冲区的字符相匹配,通过上图可以看到,查找缓冲区中没有与字符‘R’相等的符号。所以偏移量为0,其长度也为0,字符编码是‘R’。所以得出其三元组为:<0, 0, C(L)>。得到如下图所示的编码。

    最后,还剩下字符‘D’未编码,通过前面的步骤可知,查找缓冲区中没有与之匹配的字符,所以该三元组是<0, 0, C(D)>。最终完成对序列字符“HELLOWORLD”的编码操作,如下图所示:

    对于LZ编码,其整个压缩过程可以划分为以下三个步骤:

    (1)  用搜索缓冲区中可用的模式查找从当前位置开始的字符串的最长匹配。

    (2)  输出一个三元组<o, l, c>

    o:偏移量,表示为了找到匹配字符串的开始,我们需要向后移动的位置数。

    l:表示匹配的长度。

    c:字符,表示匹配后找到的字符。

    (3) 向右移动查找指针 + 1。

    3.3 LZ编码过程中的三种可能性

    通过上面对LZ编码过程的描述,可以看出,编码器使用LZ算法对一个符号序列进行压缩时候,可能会遇到以下几种情形。

    (1) 查找缓冲区里存在与先行缓冲区中待编码的字符(即存在匹配项)。

    (2) 查找缓冲区里没有与先行缓冲区中待编码字符匹配的字符。

    (3) 查找缓冲区中有匹配字符串,且该字符串在先行缓冲区字符串中延伸。

    前面(1)和(2)两种情形好理解,即找到与未找到问题。对于第(3)项的理解,需要记住这样一个事实。即对于LZ算法,仅要求匹配项的字符位置起点(即查找与先行缓冲区中的待编码字符)位于查找缓冲区中,但是若匹配到先行缓冲区中的多个字符,则其终点可以延续到先行缓冲区中。借助这段话,再来理解情形(3),就相对容易许多。

    3.4 LZ解码过程

    由于LZ算法是无损压缩算法,这意味着我们能够完全恢复原始的数据,因此,我们不能从随机的LZ三元组开始解压缩。相反,我们必须得从初始的三元组开始解压缩,因为LZ编码的三元组是基于搜索缓冲区的。

    假设我们已经完成对字符‘H’、‘E’、‘L’、‘L’、‘O’、‘W’的编码,如下图所示。

    注意,编码与解码过程中 其窗口(查找缓冲区,先行缓冲区)大小是固定的,否则,其解压缩过程将会以失败而告终。

    现在依次对上面的三元组:<2, 1, C(R)><0, 0, C(L)><0, 0, C(D)>进行解码。

    (1)  解码<2, 1, C(R)>

    由于其偏移量(offset)等于2,所以我们将查找指针(向左)移动两位;而字符匹配的长度(length)是1,所以我们将查找指针所指向的字符复制一个。其解码过程如下图所示:

    该三元组解析完成之后,得到的窗口图如下:(2)  解码<0, 0, C(L)>

    由于偏移量(offset)等于0,且匹配字符长度为0,则表明在查找缓冲区中没有与之匹配的内容,且下一个字符是‘L’。所以则在已解码的字符串后面增加一个字符‘L’,并将窗口移动一个字符。如下图所示:

    (3)  解码<0, 0, C(D)>

    和解码<0, 0, C(L)>一样,由于其偏移量和匹配长度都为0,所以其下一个字符是‘D’。则最终解码(压缩)得到的完整字符串是:HELLOWORLD。如下图所示:

    3.5 LZ算法实现

    在github上有一份 LZ算法 的源码实现。该算法中使用了二叉树来作为编码过程中的偏移量和长度等索引,以加快编码、解码的速度。针对这个LZ算法的源码,后期将专门写一篇文章来进行分析、学习。

    4. 数据压缩优缺点

    没有任何一件事物是完美的,数据压缩亦是如此。既然有优点,肯定也有它的缺点所在。下面分别对数据压缩的优缺点进行一个简单的概述。

    4.1 优点

    (1)  同一个数据文件,需要更少的磁盘空间。这意味着可以存储更多的数据文件;

    (2) 文件传输、读写速度更快。

    4.2 缺点

    (1)  增加了CPU的负载,对于一些较为复杂的压缩算法,尤其如此。

    (2) 增加了复杂性;

    (3) 提高了传输误差影响。




    往期推荐

    • SQL中GROUP BY的这些使用诀窍,你都学“废”了吗?

    • C/C++中extern关键字,它还得这么用

    • 为什么空类的大小不为0

    • 基类析构函数总是应该为virtual吗?

    • PostgreSQL数据库体系架构

    🧐3👇

    浏览 180
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报
    AQS 原理剖析
    ytao
    0
    图片压缩原理
    前端迷
    0
    Ruby原理剖析
    《Ruby原理剖析》解开Ruby编程语言的魔法面纱。全书图文并茂、深入浅出地剖析了Ruby编程语言的
    Ruby原理剖析
    0
    Ruby原理剖析
    Ruby原理剖析
    0
    JSON.hpackJSON压缩算法
    JSON.hpack 是一个用来压缩 JSON 数据的工具包和算法,目前提供了 PHP 和 C# 两
    JSON.hpackJSON压缩算法
    0
    JSON.hpackJSON压缩算法
    JSON.hpack是一个用来压缩JSON数据的工具包和算法,目前提供了PHP和C#两种语言的版本。压缩前:[{name:"Andrea",age:31,gender:"Male",skilled:t
    JSON.hpackJSON压缩算法
    0
    Zopfli开源压缩算法
    Zopfli压缩算法是一个新的兼容zlib(gzip,deflate)的压缩器,该压缩器压缩时需要更多的时间(大约慢100倍),但压缩率比zlib和其他兼容压缩器要好上5%。目前这只是一个算法。
    Zopfli开源压缩算法
    0
    TaiShan图片压缩算法
    TaiShanLuban的重构版本,感谢Luban作者提供的算法,此项目中含有大量Luban的原始代码。本人只做了整体架构的重构。原地址:https://github.com/Curzibn/Luba
    TaiShan图片压缩算法
    0
    Zopfli开源压缩算法
    Zopfli 压缩算法是一个新的兼容 zlib (gzip, deflate) 的压缩器,该压缩器压
    Zopfli开源压缩算法
    0
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报

    深圳SEO优化公司济宁网站优化软件多少钱恩施百度关键词包年推广公司网站关键词优化推荐龙岗百度竞价潮州优秀网站设计武汉网页设计价格巴中网站搜索优化多少钱天水百搜标王推荐永州企业网站制作哪家好和田模板推广来宾如何制作网站哪家好临沧营销型网站建设价格北京品牌网站设计公司岳阳百姓网标王公司昆明优化多少钱宿州模板制作哪家好海口关键词排名包年推广哪家好绵阳关键词按天收费塘坑网站制作设计哪家好娄底百度网站优化价格黔东南网站优化按天扣费公司沈阳阿里店铺托管推荐珠海优化多少钱铁岭网站制作设计推荐白银网站搭建昭通网站优化按天收费多少钱飞来峡网站设计公司聊城关键词按天扣费阜新百度爱采购多少钱常德模板制作报价歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

    深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化