lzma算法分析
这几天在公司主要在做压缩相关,记录一下所得。
目前业界主流的压缩算法感觉并不多,好用的就Huffman,lz系列,其他的像差分编码,vlq编码,感觉只能做个数据预处理,或者一种小范围的压缩。
lz系列有很多,主要有lz77 lz78 lzma,基本思想是一样的,都是一种字典编码,如,我有一段文本,里面有“abcdefgabcde”,那么后面的abcde并没有必要,可以用前面的替代,所以,其实可存储为“abcdefg65”,6代表offset,5代表length,既用距离当前位置6字节,长度为5的字节串表示当前字节串,由此就减少了三个字节,当然,这里要求0和5也要是u8类型,或者更小。
lz系列核心算法其实很简单,就是这样,但却是业界压缩效果最好的算法,大道至简啊。
lzma就是这么做的,在这里,思考这么几个问题:
1:当压缩算法扫描到中间某段位置时,如何和前面的内容进行快速比较。
2:如何区分当前是压缩的内容,还是未压缩的内容。
首先回答第一个问题,很简单,用哈希,笔者采用了FNV哈希算法,效果挺好的,用c++stl中的hash不知道效果如何,不过其实后来发现,哈希冲突在这里并不严重,一个好的哈希只能带来速度和内存的提升了,没办法提升压缩率的。然后我们如何解决哈希冲突呢,hash冲突这里其实是重点,所表达的就是可能出现了相同字节串。
我们先说这个算法如何工作,