有关LZF算法的相关解析文档比较少,但是Apple对LZF的开源,可以让我们对该算法进行一个简单的解析。LZFSE 基于 Lempel-Ziv ,并使用了有限状态熵编码。LZF采用类似lz77和lzss的混合编码。使用3种“起始标记”来代表每段输出的数据串。

接下来看一下开源的LZF算法的实现源码。

1.定义的全局字段:

       private readonly long[] _hashTable = new long[Hsize];

        private const uint Hlog = ;

        private const uint Hsize = ( << );

        private const uint MaxLit = ( << );

        private const uint MaxOff = ( << );

        private const uint MaxRef = (( << ) + ( << ));

2.使用LibLZF算法压缩数据:

        /// <summary>
/// 使用LibLZF算法压缩数据
/// </summary>
/// <param name="input">需要压缩的数据</param>
/// <param name="inputLength">要压缩的数据的长度</param>
/// <param name="output">引用将包含压缩数据的缓冲区</param>
/// <param name="outputLength">压缩缓冲区的长度(应大于输入缓冲区)</param>
/// <returns>输出缓冲区中压缩归档的大小</returns>
public int Compress(byte[] input, int inputLength, byte[] output, int outputLength)
{
Array.Clear(_hashTable, , (int)Hsize);
uint iidx = ;
uint oidx = ;
var hval = (uint)(((input[iidx]) << ) | input[iidx + ]);
var lit = ;
for (; ; )
{
if (iidx < inputLength - )
{
hval = (hval << ) | input[iidx + ];
long hslot = ((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ));
var reference = _hashTable[hslot];
_hashTable[hslot] = iidx;
long off;
if ((off = iidx - reference - ) < MaxOff
&& iidx + < inputLength
&& reference >
&& input[reference + ] == input[iidx + ]
&& input[reference + ] == input[iidx + ]
&& input[reference + ] == input[iidx + ]
)
{
uint len = ;
var maxlen = (uint)inputLength - iidx - len;
maxlen = maxlen > MaxRef ? MaxRef : maxlen;
if (oidx + lit + + >= outputLength)
return ;
do
len++;
while (len < maxlen && input[reference + len] == input[iidx + len]);
if (lit != )
{
output[oidx++] = (byte)(lit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != );
}
len -= ;
iidx++;
if (len < )
{
output[oidx++] = (byte)((off >> ) + (len << ));
}
else
{
output[oidx++] = (byte)((off >> ) + ( << ));
output[oidx++] = (byte)(len - );
}
output[oidx++] = (byte)off;
iidx += len - ;
hval = (uint)(((input[iidx]) << ) | input[iidx + ]);
hval = (hval << ) | input[iidx + ];
_hashTable[((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ))] = iidx;
iidx++;
hval = (hval << ) | input[iidx + ];
_hashTable[((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ))] = iidx;
iidx++;
continue;
}
}
else if (iidx == inputLength)
break;
lit++;
iidx++;
if (lit != MaxLit) continue;
if (oidx + + MaxLit >= outputLength)
return ; output[oidx++] = (byte)(MaxLit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != );
}
if (lit == ) return (int)oidx;
if (oidx + lit + >= outputLength)
return ;
output[oidx++] = (byte)(lit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != ); return (int)oidx;
}

3.

        /// <summary>
/// 使用LibLZF算法解压缩数据
/// </summary>
/// <param name="input">参考数据进行解压缩</param>
/// <param name="inputLength">要解压缩的数据的长度</param>
/// <param name="output">引用包含解压缩数据的缓冲区</param>
/// <param name="outputLength">输出缓冲区中压缩归档的大小</param>
/// <returns>返回解压缩大小</returns>
public int Decompress(byte[] input, int inputLength, byte[] output, int outputLength)
{
uint iidx = ;
uint oidx = ;
do
{
uint ctrl = input[iidx++]; if (ctrl < ( << ))
{
ctrl++; if (oidx + ctrl > outputLength)
{
return ;
} do
output[oidx++] = input[iidx++];
while ((--ctrl) != );
}
else
{
var len = ctrl >> ;
var reference = (int)(oidx - ((ctrl & 0x1f) << ) - );
if (len == )
len += input[iidx++];
reference -= input[iidx++];
if (oidx + len + > outputLength)
{
return ;
}
if (reference < )
{
return ;
}
output[oidx++] = output[reference++];
output[oidx++] = output[reference++];
do
output[oidx++] = output[reference++];
while ((--len) != );
}
}
while (iidx < inputLength); return (int)oidx;
}

以上是LZF算法的代码。

Apple的LZF算法解析的更多相关文章

  1. 地理围栏算法解析(Geo-fencing)

    地理围栏算法解析 http://www.cnblogs.com/LBSer/p/4471742.html 地理围栏(Geo-fencing)是LBS的一种应用,就是用一个虚拟的栅栏围出一个虚拟地理边界 ...

  2. KMP串匹配算法解析与优化

    朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...

  3. Peterson算法与Dekker算法解析

    进来Bear正在学习巩固并行的基础知识,所以写下这篇基础的有关并行算法的文章. 在讲述两个算法之前,需要明确一些概念性的问题, Race Condition(竞争条件),Situations  lik ...

  4. python常见排序算法解析

    python——常见排序算法解析   算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...

  5. Java虚拟机对象存活标记及垃圾收集算法解析

    一.对象存活标记 1. 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1:当引用失效时,计数器就减1:任何时刻计数器都为0的对象就是不可能再被使用的. 引用计数算法(Re ...

  6. JVM垃圾回收算法解析

    JVM垃圾回收算法解析 标记-清除算法 该算法为最基础的算法.它分为标记和清除两个阶段,首先标记出需要回收的对象,在标记结束后,统一回收.该算法存在两个问题:一是效率问题,标记和清除过程效率都不太高, ...

  7. DeepFM算法解析及Python实现

    1. DeepFM算法的提出 由于DeepFM算法有效的结合了因子分解机与神经网络在特征学习中的优点:同时提取到低阶组合特征与高阶组合特征,所以越来越被广泛使用. 在DeepFM中,FM算法负责对一阶 ...

  8. GBDT+LR算法解析及Python实现

    1. GBDT + LR 是什么 本质上GBDT+LR是一种具有stacking思想的二分类器模型,所以可以用来解决二分类问题.这个方法出自于Facebook 2014年的论文 Practical L ...

  9. 最长上升子序列(LIS)n2 nlogn算法解析

    题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...

随机推荐

  1. 关于DOM的一些笔记(二)

    1.选择符API (1).querySelector()方法 querySelector()方法接受一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null. 通过Docu ...

  2. MySQL修改root密码的多种方法

    不知道在cmd模式下是不是区分大小写,我大写成功了,小写没成功,不知是我拼写的错误,还是区分大小写!!?? 方法1: 用SET PASSWORD命令 mysql -u root mysql> S ...

  3. 新版 itextsharp pdf code

    using System; using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; namespace iTextShar ...

  4. bzoj1510: [POI2006]Kra-The Disks(单调栈)

    这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...

  5. 使用CSS3制作三角形小图标

    话不多说,直接写代码,希望能够对大家有所帮助! 1.html代码如下: <a href="#" class="usetohover"> <di ...

  6. 初识Python

    Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  7. SQL Server复制出错文章集锦

    SQL Server复制出错文章集锦 为了方便大家对数据库复制过程中出错的时候更好地解决问题 本人收集了SQL Server相关复制出错解决的文章   The process could not ex ...

  8. Visual Studio 2015 前端开发工作流

    Visual Studio 2015 CTP 5,全称为 Visual Studio 2015 Community Technology Preview 5,意为社区技术预览版,之前的版本为:Visu ...

  9. ASP.NET MVC 路由(四)

    ASP.NET MVC路由(四) 前言 在前面的篇幅中我们讲解路由系统在MVC中的运行过程以及粗略的原理,想必看过前面篇幅的朋友应该对路由有个概念性的了解了,本篇来讲解区域,在读完本篇后不会肯定的让你 ...

  10. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB

    您创建的MovieDBContext类负责处理连接到数据库,并将Movie对象映射到数据库记录的任务中.你可能会问一个问题,如何指定它将连接到数据库? 实际上,确实没有指定要使用的数据库,Entity ...