写在前边

最近在做一些关于网络优化的一些事情,涉及到对纯数据(Data、字符串、Json等)进行压缩,用到了Deflate压缩算法,这里就简单说一下如何用OC实现 Deflate

先看代码 (后面会给出详细解析)

Deflate.h

//
//  Deflate.h
//  CompressionTest#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Deflate : NSObject+ (NSData *)compress: (NSData *)data;
+ (NSData *)decompress: (NSData *)data;
@endNS_ASSUME_NONNULL_END

Deflate.m

//
//  Deflate.m
//  CompressionTest#import "Deflate.h"#include <zlib.h>#define CHUNK 16384@implementation Deflate/**Deflate 压缩@param data 需要压缩的数据@return 返回压缩数据*/
+ (NSData *)compress:(NSData *)data {if ([data length] == 0) return data;// 初始化 z_streamz_stream stream;stream.zalloc = Z_NULL;stream.zfree = Z_NULL;stream.opaque = Z_NULL;stream.total_out = 0;stream.next_in = (Bytef *)[data bytes];stream.avail_in = (int)[data length];// Compresssion Levels://   Z_NO_COMPRESSION//   Z_BEST_SPEED//   Z_BEST_COMPRESSION//   Z_DEFAULT_COMPRESSIONif (deflateInit2(&stream,Z_DEFAULT_COMPRESSION,Z_DEFLATED,-15,MAX_MEM_LEVEL,Z_DEFAULT_STRATEGY) != Z_OK) return nil;NSMutableData * compressed = [NSMutableData dataWithLength: CHUNK];do {if (stream.total_out >= [compressed length])// 追加长度[compressed increaseLengthBy:CHUNK];stream.next_out = [compressed mutableBytes] + stream.total_out;stream.avail_out = (uint)[compressed length] - (uint)stream.total_out;deflate(&stream, Z_FINISH);} while (stream.avail_out == 0);deflateEnd(&stream);[compressed setLength: stream.total_out];return [NSData dataWithData:compressed];
}/**Deflate 解压缩@param data 需要解压数据@return 已经解压的数据*/
+ (NSData *)decompress:(NSData *)data {if ([data length] == 0) return data;// 初始化 z_streamz_stream strm;strm.zalloc = Z_NULL;strm.zfree = Z_NULL;strm.opaque = Z_NULL;strm.total_out = 0;strm.next_in = (Bytef *)[data bytes];strm.avail_in = (int)[data length];unsigned full_length = (int)[data length];unsigned half_length = (int)[data length] / 2;NSMutableData * decompressed = [[NSMutableData alloc]initWithLength: full_length + half_length];BOOL done = false;int status;if (inflateInit2(&strm, -15) != Z_OK) return nil;while (!done) {if (strm.total_out >= [decompressed length])[decompressed increaseLengthBy: half_length];strm.next_out = [decompressed mutableBytes] + strm.total_out;strm.avail_out = (uint)[decompressed length] - (uint)strm.total_out;status = inflate(&strm, Z_SYNC_FLUSH);if (status == Z_STREAM_END)done = YES;else if (status != Z_OK)break;}if (inflateEnd(&strm) != Z_OK) return nil;if (done) {[decompressed setLength: strm.total_out];return [NSData dataWithData:decompressed];}return nil;
}@end

相关概念

deflate(RFC1951):一种压缩算法,使用LZ77和哈弗曼进行编码;
zlib(RFC1950):一种格式,是对deflate进行了简单的封装,他也是一个实现库(delphi中有zlib,zlibex)
gzip(RFC1952):一种格式,也是对deflate进行的封装。

gzip = gzip头 + deflate编码的实际内容 + gzip
zlib = zlib头 + deflate编码的实际内容 + zlib

基础数据结构

z_stream : 压缩算法,压缩程度以及输入输出buffer和长度等都保存在这里,可以理解为压缩上下文。

常用的函数

deflateInit : 参数比较少,里面的实现其实是调用的deflateInit2

deflateInit2: 压缩初始化的基础函数,有很多参数,下面会重点介绍。

deflate : 压缩函数。

deflateEnd : 压缩完成以后,释放空间,但是注意,仅仅是释放deflateInit中申请的空间,自己申请的空间还是需要自己释放。

inflateInit : 解压初始化函数,内部调用的inflateInit2

inflateInit2 : 解压初始化的基础函数,后面重点介绍。

infalte : 解压函数。

inflateEnd : 同deflateEnd作用类似。

compress : 全部附加选项默认压缩,内部调用compress2。

compress2 : 带level的压缩方式。

uncompress : 解压缩。

压缩函数介绍

deflateInit2 : 初始化函数

函数原型为 :

int ZEXPORT deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, intstrategy)

z_stream:这个是压缩上下文,我们依照官方给的例子进行初始化

strm.zalloc = NULL;
strm.zfree = NULL;
strm.opaque = NULL;strm.next_in = 你的待压缩数据
strm.next_out = 压缩以后数据存储的buffer
strm.avail_in = 待压缩数据的长度
strm.avail_out = 压缩数据存储buffer的长度.

level: 压缩的等级,目前有四个值

#define Z_NO_COMPRESSION         0   //不压缩
#define Z_BEST_SPEED             1  //速度优先,可以理解为最低限度的压缩.
#define Z_BEST_COMPRESSION       9  //压缩优先,但是速度会有些慢
#define Z_DEFAULT_COMPRESSION  (-1) //默认选项,compress里面用的就是这个选项
/* compression levels */

method: 值只有一个,当前唯一的defalte压缩方法,用于以后扩展

#define Z_DEFLATED   8
/* The deflate compression method (the only one supported in this version) */

windowBits: 窗口比特数

*    -(15 ~ 8) : 纯deflate压缩
*   +(15 ~ 8) : 带zlib头和尾
*   > 16 : 带gzip头和尾

memLevel: 目前只有一个选项,MAX_MEM_LEVEL,无非是运行过程中对内存使用的限制.

/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
#  ifdef MAXSEG_64K
#    define MAX_MEM_LEVEL 8
#  else
#    define MAX_MEM_LEVEL 9
#  endif
#endif

strategy :用于调整压缩算法,直接给默认就行Z_DEFAULT_STRATEGY.

#define Z_FILTERED            1  //用于由filter(或者称为predictor)生成的数据
#define Z_HUFFMAN_ONLY        2 //用于强制哈夫曼编码(不做字符匹配)
#define Z_RLE                 3 //限制匹配长度为1
#define Z_FIXED               4 //阻止使用动态哈夫曼编码,从而允许获得更简单的解码
#define Z_DEFAULT_STRATEGY    0 //用于普通数据
/* compression strategy; see deflateInit2() below for details */

Z_FILTERED,用于由filter(或者称为predictor)生成的数据.过滤的数据包含很多小的随机数据。这种情况下,压缩算法能够获得更好的压缩效果。该选项可以强制更多的哈夫曼编码和更少的字符匹配。有时候可以作为Z_DEFAULT_STRATEGY和Z_HUFFMAN_ONLY的折衷。
Z_FIXED,阻止使用动态哈夫曼编码,从而允许获得更简单的解码。
strategy参数只影响压缩比,而不会影响到压缩输出的正确性,因此没有正确的设置也不要紧。

deflate 压缩函数

函数原型 :

ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));

解压函数介绍

inflateInit2 初始化

原型函数

inflateInit2(z_streampstrm, int windowBits)

strm: 和deflate一样,初始化三个回调以后即可,有的参考文档说还需要初始化第四个选项,具体记不清哪个了,不过我试过以后发现貌似不用。

windownBits : 含义和deflateInit2一样,而且一定要对应起来.

inflate 解压

函数原型

ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));

z_streamp : 四个参数.

strm.next_in = 你的待解压数据
strm.next_out = 解压以后数据存储的buffer
strm.avail_in = 待解压数据的长度
strm.avail_out = 解压数据存储buffer的长度.

flush : 和deflate一样,如果是Z_NO_FLUSH说明还有数据没有解压,如果是Z_FINISH说明这是最后一包待解压数据.

inflateEnd: 释放上面两步骤里面申请的资源.

uncompress :

函数原型 :

ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen));

dest : 解压以后的数据存在这里

destLen : dest 大小

source : 待解压数据buffer

sourceLen : 待解压数据长度

其实这个函数就是简单封装了inflateInit, inflate, inflateEnd.同样,这个函数只适合单独解压场景,不适合需要多次传入的场景.

相关链接:

https://yq.aliyun.com/articles/40985
https://github.com/tsolomko/SWCompression

zlib-Deflate压缩算法相关推荐

  1. Gzip Zlib PNG 压缩算法【转】

    gzip,zlib,以及图形格式png,使用的是同一个压缩算法deflate.我们通过对gzip源码的分析来对deflate压缩算法做一个详细的说明.我阅读的gzip版本为 gzip-1.2.4.我们 ...

  2. 文章分享:Gzip 格式和 DEFLATE 压缩算法详解

    Introduction 引言: 当键入 tar -zcf src.tar.gz src 时,就可以将 src 下的所有文件打包成一个 tar.gz 格式的压缩包.这里的 "tar" ...

  3. GZip、Deflate压缩算法对应的C#压缩解压函数

    GZip解压函数 View Code GZip压缩函数 View Code 1 /// <summary> 2 /// GZip压缩函数 3 /// </summary> 4 ...

  4. java restfulapi 返回文件base64_Java反序列化:一次构造后Ysoserial Payload

    前言 在一次应用安全测试中发现了一个的Java反序列化漏洞,该漏洞最终导致未经身份验证的远程代码执行.经过实践,发现利用此漏洞并不像之前使用Ysoserial生成默认payload那样简单. 所以在本 ...

  5. (二)Java网络编程之爆肝HTTP、HTTPS、TLS协议及对称与非对称加密原理!

    引言 在上篇文章中,已经讲明了当下计算机网络的基础知识,其中对网络体系结构.分层模型.TCP/IP协议簇.....等多方面内容进行了阐述,而在本章会分析到网络知识中另外两个大名鼎鼎的协议:HTTP/H ...

  6. Zlib压缩算法:LZ77、LZ78、霍夫曼编码、滑动窗口、Rabin-Karp算法、哈希链、I/O缓冲区

    Table of Contents 1.简介 1.1 什么是zlib 2.压缩算法 2.1 放气 2.2 LZ77 2.2.1 滑动窗口 2.2.2 长距离对 2.3 霍夫曼编码 3. zlib的实现 ...

  7. 字符编码、Unicode原理、数据流压缩Zlib与Miniz的实现

    字符集和字符编码的区别和联系 字符集:多个字符的集合.例如 GB2312 是中国国家标准的简体中文字符集,GB2312 收录简化汉字(6763 个)及一般符号.序号.数字.拉丁字母.日文假名.希腊字母 ...

  8. zlib解压 被压缩的PDF(关键字FlateDecode)

    PDF被压缩了,但从网上看这个压缩算法就是zlib的压缩算法,下面的乱码就是压缩导致的乱码,现在需要把这些乱码复原 %PDF-1.7 %溷弦 4 0 obj <</Length 3 0 R ...

  9. 数据流压缩之应用篇zlib库

    关于数据流压缩的原理,lz77以及huffman编码可以参考上一篇: https://blog.csdn.net/sesiria/article/details/116835301 本篇将包含以下内容 ...

  10. 数据流压缩原理实现(huffman编码,LZ77压缩算法)

    1. 压缩原理deflate算法 a) LZ77 算法原理 b) Huffman算法原理 c) Huffman算法测试实例 2.  关于zlib库的实际应用以及gzip格式分析查看下一篇 一.数据压缩 ...

最新文章

  1. RabbitMQ Node.js 示例
  2. spring源码分析之spring-jdbc模块详解
  3. 开关电源雷击浪涌整改_大佬多年经验总结,开关电源EMI整改策略
  4. 同期及上期数据对比处理示例.sql
  5. Androida规划nt打包
  6. excel导入linux乱码怎么解决方法,,请大家都来看下,Excel导入有乱码?原因出在哪里?应该怎么解决?...
  7. 安装java 并配置环境变量_安装Java JDK并配置环境变量
  8. 2017.10.23学习知识总结回顾及编写新网页
  9. Phonetics: Lecture Three 语音 第三课 Teacher:Patrick
  10. Linux系统知识汇总
  11. electron入门笔记(三)- 引入bootstrap
  12. 前端项目emoji表情包的使用
  13. 月薪50K的测试工程师,要求原来是这样!
  14. 京东股权众筹投后总结和反思
  15. iOS视频——视频文件、播放视频
  16. 写给通信年轻人的27个忠告
  17. NLS(National Language Support)
  18. SQL sever 数据库数据类型
  19. Python 列表、元素、字典
  20. stlinkv2红灯闪烁_ST-LINK V2 DIY笔记(一)

热门文章

  1. 服务器版本与操作系统兼容性,服务器跟操作系统兼容性
  2. 微信小程序使用高德API获取位置信息
  3. multisim仿真 电流控制的电压源电路连接方法
  4. 大学计算机应用实验项目综合报告书,大学计算机应用基础实验报告册_2010版_.doc...
  5. 这样“断舍离”,你会活得更高级
  6. python图片转化为素描图
  7. 一般大学生的计算机水平,现代大学生应该具备怎样的计算机水平?
  8. 图像增强-点处理方法总结
  9. 如何学习python+人工智能
  10. 对方向导数和梯度的理解