fastlz - FastLZ压缩
作者:沈园园
一、概述
FastLZ 和 miniz 都是流行的压缩库,但它们在设计目标、压缩算法、性能特点等方面有显著区别,适用于不同的应用场景。
FastLZ 是一款高效且小巧的开源压缩库,主要用于实现基于 LZ77 算法的字节对齐数据压缩。
LZ77(Lempel-Ziv 1977)是数据压缩领域的一种基础方法,其核心思想是通过查找源数据中的重复模式来减少存储空间。
适用于压缩文本/段落序列、原始像素数据序列或具有大量重复的任何其他数据块。但是不打算用于图像、视频和其他通常已经以最佳压缩形式存在的格式的数据。
FastLZ 的重点是非常快速的压缩和解压缩。
miniz是一个单一文件的小型压缩库,它是zlib的一个替代品,专门为需要轻量级压缩解决方案的项目设计,它被设计成可以轻松地集成到项目中,并且具有最小的依赖性。
miniz的主要特点包括:
- 支持zlib兼容的压缩和解压缩。
- 单个源文件实现,易于集成。
- 小的内存占用,适合资源受限的环境。
- 支持流式压缩和解压缩。
miniz库接近200k, fastlz只需要32k+原始数据大小 压缩比, miniz的压缩比要好于fastlz
总结:FastLZ 是 "速度优先"的轻量选择,miniz 是 "兼容与压缩率优先" 的通用选择。
二、核心示例
1、核心示例是指:使用本库文件提供的核心API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的demo,请参考 LuatOS仓库 中各个产品目录下的demo/fastlz
-- 与miniz库的差异
-- 内存需求量小很多, miniz库接近200k, fastlz只需要32k+原始数据大小
-- 压缩比, miniz的压缩比要好于fastlz
-- 准备好数据
local bigdata = "123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw"
-- 压缩之
local cdata = fastlz.compress(bigdata)
-- lua 的 字符串相当于有长度的char[],可存放包括0x00的一切数据
if cdata then
-- 检查压缩前后的数据大小
log.info("fastlz", "before", #bigdata, "after", #cdata)
log.info("fastlz", "cdata as hex", cdata:toHex())
-- 解压, 得到原文
local udata = fastlz.uncompress(cdata)
log.info("fastlz", "udata", udata)
end
三、常量详解
核心库常量,顾名思义是由合宙LuatOS内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
fastlz核心库没有常量。
四、函数详解
fastlz.compress(data, level)
快速压缩
参数
data
参数含义:待压缩的数据
数据类型:string;
取值范围:压缩后的数据不能大于32KB;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:"123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw";
level
参数含义:压缩级别
数据类型:int;
取值范围:压缩级别,默认1, 可选1或者2, 2压缩率略高但速度稍慢,1速度更快但压缩率更低,可根据需求选择;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:1;
返回值 local cdata = fastlz.compress(data, level)
cdata
含义说明:若压缩成功,返回数据字符串, 否则返回nil
数据类型:string或者nil;
取值范围:长度小于等于32KB的string类型的数据或者nil值;
注意事项:暂无;
返回示例:可能会含有不可见字符通过cdata:toHex()格式打印;
示例
-- 准备好数据
local bigdata = io.readFile("/luadb/test.txt") or "1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbn"
-- 压缩之后
local cdata = fastlz.compress(bigdata,1)
local cdata2 = fastlz.compress(bigdata,2)
-- lua 的 字符串相当于有长度的char[],可存放包括0x00的一切数据
if cdata then
-- 检查压缩前后的数据大小
log.info("fastlz", "before", #bigdata, "after", #cdata,#cdata2)
--before 503 after 50 48(对应例子中503字节数据)
--before 5030 after 107 73 (从文件中读取5030字节数据)
--before 30180 after 395 172 (从文件中读取30180字节数据)
log.info("fastlz", "cdata as hex", cdata:toHex())
--1F3132333435363738393071776572747975696F706173646667686A6B6C7A78630376626E6DE0FD23E0BF2304786376626E 100
end
fastlz.uncompress(data, maxout)
快速解压
参数
data
参数含义:待解压的数据
数据类型:string;
取值范围:长度小于32KB的任意字符串数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:可以先把数据压缩,然后解压压缩后的数据看是否相同;
maxout
参数含义:解压后的最大数据大小
数据类型:number;
取值范围:默认是4096, 可按需调整(比如设置为压缩前的原始数据长度);
是否必选:可选传入此参数,不填时,默认是4096;
注意事项:暂无;
参数示例:8192;
返回值 local udata = fastlz.uncompress(data, maxout)
udata
含义说明:若解压成功,返回数据字符串, 否则返回nil
数据类型:string或者nil;
取值范围:无特别限制;
注意事项:暂无;
返回示例:"123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw";
示例
-- 准备好数据
local bigdata = "123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;"
-- 压缩之
local cdata = fastlz.compress(bigdata)
-- lua 的 字符串相当于有长度的char[],可存放包括0x00的一切数据
if cdata then
-- 检查压缩前后的数据大小
log.info("fastlz", "before", #bigdata, "after", #cdata)--before 112 after 75
log.info("fastlz", "cdata as hex", cdata:toHex())--1F3132336A666F697134686C6B666A626E617364696C66687571776F3B686661730E686670397177333868726661696F7320130D69756F616768666C756165697377E0223F0461696F733B 150
-- 解压, 得到原文
local udata = fastlz.uncompress(cdata)
log.info("fastlz", "udata", udata)--123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;
end
五、产品支持说明
支持LuatOS开发的产品中:
Air780EPM不支持此功能;
Air700ECH/Air780EHN/EHU/EHM/EHV/EGH/Air8000的11号、12号、111号、112号固件不支持此功能。
Air8101/A/Air6101/A的1号、2号、3号固件都支持此功能。