zlib压缩原理

news2024/11/17 3:29:19

数据压缩的本质

去除数据中的冗余信息,对于ABABABABABABAB字样的字符串,AB出现了7次,占用14个字节,如果将该字符串编码为7AB,只占用3个字节。

为什么需要对数据压缩

数据需要存储或者传输,为了节省磁盘空间和网络带宽,在存储或传输时可以将数据先进行压缩,到真正需要使用数据的时候再进行解压。

zlib压缩

zlib压缩是一种无损压缩,底层使用deflate数据流压缩算法。

zlib压缩的特点:

  • 无损压缩

  • 压缩率取决于数据的重复性

deflate的三种压缩模型

  • 不压缩数据。对于已经压缩过的数据,不再进行压缩。

  • 压缩数据。先用LZ77进行压缩,再使用huffman编码。压缩树是deflate规定的。

  • 压缩数据。先用LZ进行压缩,再使用huffman编码。压缩树是压缩其生成的

 

LZ77压缩算法

LZ77压缩算法的核心思想是对字符串进行扫描,对于前面已经出现过的子字符串,用(偏移量,匹配的字符串的长度)进行编码。LZ77中有三个重要的概念:短语字典、滑动窗口、前向缓冲区。

  • 前向缓冲区:待编码的数据

  • 滑动窗口:存放已经编码的数据

  • 短语字典:用滑动窗口中的数据更新字典,并与前向缓冲区中的数据进行匹配

LZ77算法的步骤

  • 步骤1:逐字符扫描前向缓冲区,在滑动窗口中找出匹配的最长子字符串,如果找到,则执行步骤2,如果没有找到,执行步骤3

  • 步骤2:对前向缓冲区中匹配的字符串进行编码并输出,编码的格式为(前向缓冲区中匹配开始位置距离滑动窗口中匹配开始位置的偏移量,匹配的长度),将匹配的字符串移入滑动窗口中,继续执行步骤1

  • 步骤3:将当前字符编码为(0,0,当前字符值)并输出,表示滑动窗口中没有出现过该字符,并将该字符移入到滑动窗口中,继续执行步骤1

例子

现在对ABABCBABABCAD这个字符串进行压缩。

滑动窗口大小为8,前向缓冲区大小为4。

  • 开始,执行步骤1,将ABAB四个字符读入前向缓冲区,扫描到字符A,此时滑动窗口为空,没有找到匹配,执行步骤3, 将字符A编码为(0,0,A),并将字符A移入滑动窗口中,将C移入前向缓冲区。

 

  • 继续执行步骤1,扫描到字符B,缓冲区中没有字符B,执行步骤3, 将字符B编码为(0,0,B),并将字符B移入滑动窗口中。

 

  • 继续执行步骤1,扫描到字符A,滑动窗口中有字符A,继续扫描字符A后面的字符,当前字符串为AB,滑动窗口中有AB,继续向后扫描,得到字符串ABC,但滑动窗口中没有ABC,扫描结束,执行步骤2,将AB编码为(2,2),将AB移入滑动窗口

 

  • 继续执行步骤1,扫描到字符C,缓冲区中没有字符C,执行步骤3, 将字符C编码为(0,0,C),并将字符C移入滑动窗口中

 

  • 继续执行步骤1,匹配到BAB,执行步骤2, 将BAB编码为(4,3),移动缓冲区

 

  • 继续执行步骤1,匹配到ABC,执行步骤2,将ABC编码为(6,3),移动缓冲区

 

  • 继续执行步骤1,匹配到A,执行步骤2,将A编码为(5,1),移动缓冲区

 

  • 继续执行步骤1,滑动窗口中没有字符D,执行步骤3,将D编码为(0,0,D),移动缓冲区

  • 前向缓冲区为空,结束

最终的输出为:(0,0,A),(0,0,B),(2,2),(0,0,C),(4,3),(6,3),(5,1),(0,0,D),可以按照这个序列进行解码

(0,0,A)->A

(0,0,B)->AB

(2,2)->ABAB

(0,0,C)->ABABC

(4,3)->ABABCBAB

(6,3)->ABABCBABABC

(5,1)->ABABCBABABCA

(0,0,D)->ABABCBABABCAD

Huffman编码

参考:https://blog.csdn.net/FX677588/article/details/70767446

哈夫曼(Huffman)编码算法是基于二叉树构建编码压缩结构的,它是数据压缩中经典的一种算法。算法根据文本字符出现的频率,重新对字符进行编码。我们希望出现频率越高的字符的编码后的长度越小。

重要的性质

哈夫曼编码是一种前缀编码。前缀编码指的是,任何一个字符的编码都不是同一字符集中另一个字符的编码的前缀。比如,将字符A编码为0,那么则不能将字符B编码为01。

这个性质对于解码起着重要的作用

构建哈夫曼二叉树

对于字符串“we will we will r u”,如果直接使用ASCII编码,编码后每个字符表示为(包括空格):

119 101 32 119 105 108 108 32 119 101 32 119 105 108 108 32 114 32 117,可见需要19个字节存储这段信息,共152位。

现在对每个字符出现的频率进行统计,得到下表:

  • 首先按照字符出现的频率从低到高的顺序对字符进行排序,存储到一个优先队列中,优先队列中每个元素可以看成一个节点,每个节点具有值和权重(出现的次数)两种属性

  • 为了得到哈夫曼树,需要对优先队列进行从左到右进行合并,将u作为左节点,r作为右节点,将r和u的权重(出现的次数)相加,得到一个新的节点,作为u和r的父节点。

  • 继续将这个新节点与节点i进行合并

  • 此时优先队列中的元素不再按照权重从低到高的顺序进行排列了,对优先队列进行重新排序

  • 重复进行合并与排序操作,直到优先队列中只有一个根节点,最后得到huffman树

问一个问题:为什么要将元素按照出现次数从低到高排列

根据haffman树进行编码

得到huffman树后,将该二叉树中分支中的左支路编码为0,右支路编码为1,得到编码二叉树

 

最后,根据编码二叉树得到每个字符的编码

空格:10

w:01

l:00

e:110

i:1111

r:11101

u:11100

可以看出,对于出现频率越高的字符,编码后的长度越小

字符串编码

有了上面的编码表之后,”we will we will r u”这句重新进行编码就可以得到很大的压缩,编码表示为:01 110 10 01 1111 00 00 10 01 110 10 01 1111 00 00 10 11101 10 11100。这样最终我们只需50位内存,比原ASCII码表示节约了2/3空间,效果还是很理想的。当然现实中不是简单这样表示的,还需要考虑很多问题。

解码

由于huffman编码是前缀编码,在解码时,从哈夫曼树的根开始,从左到右把二进制编码的每一位进行判别,若二进制编码为0,则选择左分支走向下一个结点;若遇到1,则选择右分支走向下一个结点

现在根据huffman树对01 110 10 01 1111 00 00 10 01 110 10 01 1111 00 00 10 11101 10 11100这个huffman编码进行解码

 

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

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

相关文章

ONNXRUNTUIME实例分割网络说明

ONNXRUNTUIME c使用(分割网络)与相关资料(暂记) initiate a env with an id name(使用id名称启动env) create session (创建会话 ) onnxenv -> sessioninputname [“x”] ,outputname [“t”]inputnodedim [[1,1,192,192…

Linux单一服务管理systemctl

基本上systemd这个启动服务机制只有systemctl命令来处理,所以全部的操作都需要使用systemctl systemctl管理单一服务 一般来说服务的启动有两个阶段,一个是开机是否启动,以及现在是否启动 systemctl【command】【unit】 command主要有&…

VS2017+OpenCV4.5.5 决策树-评估是否发放贷款

决策树是一种非参数的监督学习方法,主要用于分类和回归。 决策树结构 决策树在逻辑上以树的形式存在,包含根节点、内部结点和叶节点。 根节点:包含数据集中的所有数据的集合内部节点:每个内部节点为一个判断条件,并且…

mysql详解之innoDB

索引 Mysql由索引组织,所以索引是mysql多重要概念之一。 聚簇索引 InnoDB和MyISAm一样都是采用B树结构,但不同点在于InnoDB是聚簇索引(或聚集索引),将数据行直接放在叶子节点后面。 这里可能存在一个误区&#xff1…

【C语言】编程初学者入门训练(14)

文章目录131. kiki学结构体和指针132. kiki定义电子日历类133. 圣诞树134. 超级圣诞树131. kiki学结构体和指针 问题描述:KiKi学习了结构体和指针,他了解了结构体类型可以定义包含多个不同类型成员,而指针本质是内存地址,是引用数…

【人脸检测】Yolov5Face:优秀的one-stage人脸检测算法

论文题目:《YOLO5Face: Why Reinventing a Face Detector》 论文地址:https://arxiv.org/pdf/2105.12931.pdf 代码地址:https://github.com/deepcam-cn/yolov5-face 1.简介 近年来,CNN在人脸检测方面已经得到广泛的应用。但是许多…

【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…

过滤器和监听器

1、过滤器Filter 作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等; 使用Filter的步骤 新建类,实现Filter抽象类;重写init、doFilter、destroy方法;在SpringBoot入口中添加注解…

演示Ansible中的角色使用方法(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径:配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…

使用vue3,vite,less,flask,python从零开始学习硅谷外卖(41-82集)

第41集:这里遇到个大坑,因为这种项目有很多页面,有时候有的页面忘了保存就会出错,还很难排查,浪费了我快半天的时间。可以把vscode的代码自动保存打开,以后就不会踩坑了。 第42集:没啥好说的。 …

判断字符串中的字符的类型isdecimal();isalpha();isdigit();isalnum()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串中的字符的类型 isdecimal();isalpha();isdigit();isalnum() [太阳]选择题 对于代码中isdecimal()和isalnum()输出的结果是? s "ABc123&…

亿级高并发电商项目-- 实战篇 --万达商城项目 十一(编写商品搜索功能、操作商品同步到ES、安装RabbitMQ与Erlang,配置监听队列与消息队列)

👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

Sandboxie-沙箱软件-Plus版本(Qt)-主框架程序-SandMan.exe-创建语言文件-tr-Qt-语言国际化

文章目录1.功能介绍2.Qt语言国际化3.设置软件的语言版本4.作者答疑1.功能介绍 沙箱软件的增强版本采用Qt架构开发,核心模块与经典版本相同,本文主要介绍SandMan.exe这个主程序代码。在main.cpp这个入口函数里,有主窗口入口,如下所…

2.5|iot冯|方元-嵌入式linux系统开发入门|2.13+2.18

一、 Linux 指令操作题(共5题(共 20 分,每小题 4分)与系统工作、系统状态、工作目录、文件、目录、打包压缩与搜索等主题相关。1.文件1.1文件属性1.2文件类型属性字段的第1个字符表示文件类型,后9个字符中,…

【物联网】智慧农业病虫害精准辨识竞赛思路及代码分享

来源:投稿 作者:LSC 编辑:学姐 比赛官网: https://www.dataglobal.cn/cmpt/signUpInfo200.html 任务描述 请参赛者设计智慧农业病虫害检测系统,给出一体化问题解决方案,鼓励参赛选手结合某一果园/农作物实际情况建立…

使用 URLSearchParams 解析和管理URL query参数

介绍 首先 URLSearchParams是一个构造函数,会生成一个URLSearchParams对象,参数类型: 不传 | string | object | URLSearchParams, 并且遇到特殊字符它会自动帮我们encode 和 decode const ur…

Java模块化概述

3 模块化 3.1 模块化概述 Java语言随着这些年的发展已经成为了一]影响深远的编程语言,无数平台,系统都采用Java语言编写。但是,伴随着发展,Java也越来越庞大,逐渐发展成为-门“臃肿” 的语言。而且,无论是运行个大型的…

Vulnhub 渗透练习(五)—— lazysysadmin1

环境搭建 下载链接 vmware 打开靶机,nat 网络适配,攻击机同样。 信息收集 一个一个的看过去,这边就不贴图了。 漏洞挖掘 用 kail 的 wpscan 扫一下 wordpress,没发现漏洞。 ┌──(geng㉿geng)-[~] └─$ wpscan --url http…

【Linux06-基础IO】4.5万字的基础IO讲解

前言 本期分享基础IO的知识,主要有: 复习C语言文件操作文件相关的系统调用文件描述符fd理解Linux下一切皆文件缓冲区文件系统软硬链接动静态库的理解和制作动静态编译 博主水平有限,不足之处望请斧正! C语言文件操作 #再谈文件…

SQLSERVER2019安装步骤过程

第一步官网下载SQLSERVER软件包 目前官网只能下载最新版本2022版本。 通过迅雷下载网址 SQL Server 2019 Enterprise (x64) - DVD (Chinese-Simplified)企业版 ed2k://|file|cn_sql_server_2019_enterprise_x64_dvd_2bfe815a.iso|1632086016|58C258FF0F1D006DD3C1F5F17AF3E…