关于7-zip中Lzma算法原理的源代码分析

7zip核心算法LZMA分析心得
最近有空就研究了一下DEFLATE的LZ77压缩算法实现及7zip的LZMA压缩算法实现,现在记下相关心得如下:
一、 DEFLATE中的LZ77算法实现比较简单,具体研究的是github上的一个精简版实现miniz,源码可见https://gitee.com/tigerzyj/miniz。有几个要点要注意,一是基于字节流的字典匹配,二是哈夫曼编码,详情可以参阅RFC1951,那里说的很清楚了。有特色是哈夫曼编码的ALISTAIR MOFFAT实现方法,有些难理解,找到他的论文并亲自在纸上推算一下就能理解了。

二、 7zip中的LZMA编码是在LZ77算法上加入了基于比特流及马尔科夫链上下文的区间编码(range code)以及基于动态规划(Dynamic Programming)的深度优化,并扩大了DEFLATE中32K的字典到默认的8M(或16M,根据版本不同),理论上最大可以到4G,实际实现中最大为1536 MB,32位7zip实现中最大为128M。详情可以参见维基百科上的https://en.wikipedia.org/wiki/Lempel–Ziv–Markov_chain_algorithm,(转载地址https://www.cnblogs.com/tigerzyj/p/15334782.html)文章其它地方说得比较清楚,但DP优化说得很简单,不太好理解,看了源码花了N个小时才算看明白。具体看的源码是lzma1900的cs实现,这个实现与java实现比较容易理解。下载地址为
https://www.7-zip.org/a/lzma1900.7z

采用马尔科夫链主要利用马尔科夫随机过程来消除原始文件中的基于上下文的冗余(如英文中字母Q后面紧接的字母为U的概率远较其它字母大),而不仅仅是哈夫曼编码中单纯的基于字符出现的随机统计概率,其利用的上下文主要有当前待编码的字节位置(literal bits 【lb】\position bits 【pb】)、待编码字节的前一字节内容(literal contexts 【lc】),匹配状态以及当前编码状态机的实时状态(state)等非常复杂的机制,利用这些参数组合成一系列很复杂的状态机以匹配不同的上下文场景。不同的上下文分别对应自己的区间编码动态概率表,区间编码使用这些概率表来进行相应的编码工作。动态马尔科夫压缩相关信息可以参考https://webhome.cs.uvic.ca/~nigelh/Publications/DMC.pdf

动态规划优化主要是利用了动态规划算法(DP)来计算如何编码一段在字典中已经查到的匹配字符串,主要代码在函数GetOptimum()中,常规方法就是简单的将一对Len+Distance符号进行区间编码,而DP优化则是将这一段匹配字符串所有2到n-1阶子串的区间编码(range code)长度与常规编码长度进行比较,其中充分利用了最近用过的N(默认为4)个匹配长度来参与编码,(这样编码对象中减少一个Distance)可以有效减小常规编码长度。注意只有当最大匹配长度小于numFastBytes(fb,默认为32)参数值时DP优化才参与编码,否则就只用常规的Len+Distance来编码,这就是numFastBytes中fast的来历,因为fb越大消耗时间也越长。另外GetOptimum()函数中还利用了贪心算法以争取编码长度最小化,因此_optimum[]数组的长度被定为4096,而不只是273,就是在不断应用贪心算法过程中可能会使此优化数组变长。

DP优化中要预估区间编码的长度,以判断哪种编码策略最优,这里无法精确计算某个编码策略的实际长度,只有通过估计来实现,具体方法是将区间编码所用的RANGE内每个累积区间假定一个权重,权重的确定遵循熵编码“概率越大编码长度越小”的原则。LZMA中这个权重表是用一个二重循环人工生成的。

区间编码的具体说明可以参考叶叶的这篇论文,《区间编码的分析与实现》,写得很详细。值得説明的一点是这篇论文的区间编码是基于字节流的,编码字符只有不超过256,而LZMA的区间编码是基于比特流的,每次只编码一个比特,因此概率表的设计就很关键。

字典查询匹配字串可以用哈希链表,也可以用二进制树,参数mf可以设为(bt2、bt3、bt4或hc4)

字典匹配字串搜索次数可以由参数mc确定,默认为(16 + number_of_fast_bytes / 2) for BT* match finders and (8 + number_of_fast_bytes / 4) for HC4

如有时间再详细记录一下代码分析细节 。
————————————————


————————————————
版权声明:本文为博主「tigerzyj」的原创文章,遵循版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.cnblogs.com/tigerzyj/articles/15334742.html

posted @ 2021-09-25 16:45  神洲一号  阅读(5643)  评论(0)    收藏  举报