跳转至

fastlz - FastLZ压缩

作者:沈园园

一、概述

FastLZ 和 miniz 都是流行的压缩库,但它们在设计目标、压缩算法、性能特点等方面有显著区别,适用于不同的应用场景。

FastLZ 是一款高效且小巧的开源压缩库,主要用于实现基于 LZ77 算法的字节对齐数据压缩。

LZ77(Lempel-Ziv 1977)是数据压缩领域的一种基础方法,其核心思想是通过查找源数据中的重复模式来减少存储空间。

适用于压缩文本/段落序列、原始像素数据序列或具有大量重复的任何其他数据块。但是不打算用于图像、视频和其他通常已经以最佳压缩形式存在的格式的数据。

FastLZ 的重点是非常快速的压缩和解压缩。

miniz是一个单一文件的小型压缩库,它是zlib的一个替代品,专门为需要轻量级压缩解决方案的项目设计,它被设计成可以轻松地集成到项目中,并且具有最小的依赖性。

miniz的主要特点包括:

  1. 支持zlib兼容的压缩和解压缩。
  2. 单个源文件实现,易于集成。
  3. 小的内存占用,适合资源受限的环境。
  4. 支持流式压缩和解压缩。

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(bigdata1) 
local cdata2 = fastlz.compress(bigdata2) 
-- 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号固件都支持此功能。