Deflate内部实现(LZ77无损压缩算法)超详细图解算法版~

无损压缩算法

  • 第一阶段:重复消除 — LZ77无损压缩算法
    • 算法介绍
      • 举例
      • 压缩算法思路
      • 图解压缩过程
  • 第二阶段:位减少
    • huffman
    • 位减少

概览

  • Gzip
    • Deflate 编码(LZ77+哈夫曼)
  • Brotli
    • LZ77+哈夫曼+二阶上下文建模

Deflate 分两个阶段压缩数据:重复消除位减少

第一阶段:重复消除 — LZ77无损压缩算法

算法介绍

基于字典的无损压缩算法,它搜索重复的未压缩序列并用引用指针替换它们。

引用指针由 2 个元素定义:

  • offset距离(或偏移量):原始未压缩数据中出现的第一个现有字节的相对返回。
  • Length:重复的字节长度。

当对序列进行压缩的时候,采用 “滑动窗口” 算法,
结构如下:

  • 查找缓冲区(Search buffer),也称字典(已编码部分)
  • 先行缓冲区(Look ahead buffer),包括即将进行编码序列的一部分。每次读取数据的时候,先把一部分数据预载入前向缓冲区。为移入滑动窗口做准备。

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

滑动窗的尺寸是影响压缩性能的关键因素之一。如果滑动窗口太小,则压缩器可能会发现较少的重复数据序列,结果,压缩文件的大小将更大。如果滑动窗口太大,则压缩器可能需要花费更长的时间来查找重复的数据序列,因此压缩速度将变慢。
在这里插入图片描述

要使用 LZ77 压缩算法:

  1. 将编码位置设置为输入流的开头。
  2. 在查找缓冲区的窗口中找到最长的匹配项。
  3. 如果找到匹配,则输出指针 P。将编码位置(和窗口)向前移动 L个字节。
  4. 如果未找到匹配项,则输出空指针和先行缓冲区中的第一个字节。将编码位置(和窗口)向前移动一个字节。
  5. 如果先行缓冲区不为空,则返回步骤 2。

主要逻辑 :
通过先行缓冲区预读取数据,然后向字典中移入, 不断搜索字典中与先行缓冲区连续相匹配的最长序列,然后输出metadata标记。

举例

以微软的例子来理解算法:微软介绍:LZ77压缩算法

Input stream

Position    1    2    3    4    5    6    7    8    9
Byte        A    A    B    C    B    B    A    B    C

Output 期望压缩后得到的结果:
在这里插入图片描述

压缩后怎么能读取到原文呢?

答:需要将output进行解码,如:
(0,0)‘X’:直接推入X
(o,l):找到offset=o的位置,往后复制l个字符
在这里插入图片描述

看来最重要的一环就是如何压缩啦!让我们一起看看这个算法的思路和图解吧~

压缩算法思路

AABCBBABC串,将重复的子串用指针进行替换,
对于其中的每个元素 x 有两种情况:
     1. 前文没有任何重复的子串:输出(0,0)x
     2. 在前文能找到重复的子串:输出(offset = x和匹配子串的的距离,length = 匹配子串的长度)

图解压缩过程

字符序列移动方向:从右往左

简称:

  • buffer区:先行缓存区(未编码),这是需要匹配的字符串
  • Dictionary:查找缓存区(已编码),用来匹配buffer的字典区域
  1. 初始字符串从右往左滑动,直至占满所有buffer区,如图1
    在这里插入图片描述
                    (图1)
    在这里插入图片描述

  2. 开始遍历 图1 buffer的第一个字符’A’,因Dictionary空,未匹配到’A’ => 往左移一格(如图2),输出(0,0)A。
    (offset = A无匹配子串,距离=0,length:0,无重复子串)在这里插入图片描述                (图2)
    在这里插入图片描述

  3. 遍历 图3 buffer第一个字符"A",在Dictionary找到"A",未超过buffer黄色长度,往后遍历到编码"AB",Dictionary没有匹配到“AB”字符串,于是只编码"A",输出(1, 1)。
    在这里插入图片描述
                    (图3)

    图4,匹配长度为1,所以字符串向左偏移一个单位:
    在这里插入图片描述
                    (图4)
    在这里插入图片描述

  4. 匹配buffer区第一个字符’B’,Dictionary内未匹配,同步骤1,输出(0,0)B,左移一格。

  5. 匹配buffer区第一个字符’C’,Dictionary内未匹配,同上,输出(0,0)C,左移一格,如 图5
    在这里插入图片描述
                    (图5)
    在这里插入图片描述

  6. 匹配 图6 buffer区第一个字符’B’,offset('B’与Dictionary中匹配的’B’的距离)=2,两个查找指针同时往后移1(如图6),比较'C'vs'B'不匹配,终止,length=1,输出(2,1)
    在这里插入图片描述
                    (图6

    得到结果:
    在这里插入图片描述
                    (图7)
    在这里插入图片描述

  7. 匹配 图7 buffer区第一个字符’B’,Dictionary匹配到‘B’,分别是offset=1和offset=3,但offset=3下一字节'C'vs'A'不匹配,就近原则选择offset=1,length=1,输出(1,1)。
    在这里插入图片描述
                    (图8)
    此时已编码序列长度大于Dictionary区,有序列滑出了窗口,如图8
    在这里插入图片描述

  8. 匹配 图8 BUFFER第一个字符 ‘A’,在DICTIONARY匹配到,offset=5,往后遍历直到匹配"ABC",length=3,此时不能再往后编码否则超过BUFFER区域长度,故输出(5, 3),往左移动3格,如图:
    在这里插入图片描述
    在这里插入图片描述

第二阶段:位减少

huffman

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过哈夫曼树,我们可以将原本需要120bit(15*8)的位减少到 28bit

位减少

范式huffman树:在普通huffman树的基础上只要保存编码位长,利用位长反推编码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】Centos升级到国产操作系统OpenAnolis

一、前言 Anolis OS 7生态上和依赖管理上保持跟CentOS7.x兼容,一键式迁移脚本centos2anolis.py,实现CentOS7.x到Anolis OS 7的平滑迁移 使用迁移脚本前需要注意如下事项: 迁移涉及到软件包的重新安装,是不可逆过程,…

基于SpringBoot的社区医院管理服务系统

开头语:你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:SpringBoot框架 工具:Eclipse,Navicat,Maven…

如何提高PMC在异常停线情况下的应急处理能力?

在工业生产中,异常停线是一个常见且令人头疼的问题。它不仅会导致生产进度受阻,还可能造成资源浪费和成本增加。因此,提高PMC(生产计划与控制)在异常停线情况下的应急处理能力,对于确保生产线的稳定运行和提…

晨持绪科技:抖音小店的前景究竟怎么样

随着移动互联网的迅猛发展,短视频平台快速崛起并逐渐成为人们日常生活中不可或缺的一部分。作为国内领先的短视频平台,抖音在近年推出了“抖音小店”功能,为商家提供了一个新兴的、流量巨大的电商渠道。这一功能的推出不仅改变了传统的购物方…

算法期末整理

一 算法概述 算法的概念 通俗地讲,算法是指解决问题的一种方法或一个过程。更严格地讲,算法是由若干条指令组成的有穷序列。 算法的性质 1.输入:有0个或多个由外部提供的量作为算法的输入。 2.输出:算法产生至少一个量作为输出。…

跨境电商必备?揭秘原生IP的作用

一、什么是原生IP? 原生IP(Native IP)是指由互联网服务提供商(ISP)或服务器提供商直接分配给用户的IP地址,这种IP地址直接与用户设备或网络相连,也就是指这个IP的注册地址和服务器机房所在的国…

某宝APP参数通过SDK把APP参数转URL参数链接方法

app里参数无法在电脑端或者在没有XX宝的手机里支付, 所以需要转成H5参数进行代付操作 出某xx宝 支付sdk转h5链接方式算法

爆赞!GitHub首本Python开发实战背记手册,标星果然百万名不虚传

Python (发音:[ paiθ(ə) n; (US) paiθɔn ] n. 蟒蛇,巨蛇 ),是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。Python 具有脚本语言中最丰富…

安防监控视频平台LntonAIServer视频智能分析平台烟火检测

LntonAIServer烟火检测技术是一种先进的技术,它结合了人工智能的强大能力,专门用于识别和检测烟雾或火焰的存在。这种技术在现代社会的许多领域中都发挥着至关重要的作用,尤其是在安全监控和火警预警系统等关键领域,它的应用更是不…

Advanced RAG 08:使用 Self-RAG 打造高质量、可追溯的 RAG System

编者按: RAG 技术通过检索并利用外部知识源,能够较为有效地提升生成内容的准确性和多样性。然而,经典 RAG 流程也存在一些不足,例如不必要的检索会浪费计算资源,并可能引入无关内容或错误信息,影响生成质量…

【ai】如何在ollama中随意使用hugging face上的gguf开源模型

【背景】 ollama的pull命令可以直接pull ollama列表中现有的模型,但是ollama可以直接pull的模型大都是英语偏好(llama2有直接可以pull的chinese版本),而hugging face上则有大量多语种训练的模型,如果能直接使用huggin…

香港优才计划申请打分、材料、递交攻略,2024年获批后我来分享

香港优才计划这两年很多人弄啊,糖爸作为获批过来人,我来给大家分享香港优才计划申请攻略。 一、香港优才计划如何计算分数? 香港优才计划申请条件分2部分:第一是基本资格要求,第二是计分制度; 基本条件简…

【PL理论】(33) 类型系统:推导树证明 φ ⊢ e∶t | 继续定义关系:γ ⊢ e∶t

💬 写在前面:本章我们将讲解推导树证明,推导树实际上就是推理规则的应用。只要学会如何选择并应用适当的推理规则,证明就不是难事了。 目录 0x00 推导树证明 𝝓 ⊢ 𝒆 ∶ 𝒕 0x01 继续定义关…

《Linux运维总结:基于ARM64架构CPU使用docker-compose一键离线部署alertmanager v0.27.0高可用集群》

总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:《Linux运维篇:Linux系统运维指南》 一、部署背景 由于业务系统的特殊性,我们需要面对不同的客户部署业务系统&#xff0…

Ubuntu 24.04安装zabbix7.0.0图形中文乱码

当zabbix安装完成后,设置中文界面时,打开图形,中文内容会显示方框乱码,是因为服务器字体中没有相关的中文字体,需要更换。 1、找到中文字体,可以在网络上下载《得意黑》开源字体,也可以在windo…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 01:假想的编译器

这是一本老书,作者 Steve Maguire 在微软工作期间写了这本书,英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字,英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

MyBatis拦截器(Interceptor)的理解与实践

文章目录 1. 什么是MyBatis拦截器?2. 拦截器的基本原理3. 编写自定义拦截器3.1 示例:实现SQL执行时间统计拦截器3.2 配置拦截器 4. 实战应用场景5. 总结 🎉欢迎来到SpringBoot框架学习专栏~ ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博…

原生js制作svg 图标生成动态 tab栏切换效果(结尾附代码)

svg 图标生成动态 tab 栏 先看效果: 我想做一个 tab 栏比较美观的效果,当然切换的数据可以自己做一下,这里不演示,说一下特效如何制作。 当我点击时要将空心变为实心的这么一个效果,所以准备两个五角星样式一个是空…

Java面试八股之myBatis的优缺点

myBatis的优缺点 优点: 灵活性高: MyBatis允许直接编写原生SQL语句,这意味着你可以针对特定的数据库特性进行优化,处理复杂的查询逻辑,从而更好地满足业务需求。 易于上手: 相比Hibernate等其他ORM工具&…