缩小并修复霍夫曼代码

时间:2017-10-09 20:52:09

标签: huffman-code deflate

我试图实施一个deflate压缩器,我必须决定是否 使用静态霍夫曼代码压缩块或创建动态代码。

与静态代码相关的长度背后的基本原理是什么?

(这是rfc中包含的表格) Lit Value Bits --------- ---- 0 - 143 8 144 - 255 9 256 - 279 7 280 - 287 8 我认为静态代码更倾向于简单的ascii文本,而不是它 看起来它喜欢一点点压缩长度

决定是否使用静态代码有什么好的启发式方法?

我正在考虑从一个样本中建立一个概率分布 输入数据并根据导出的概率计算距离(可能是EMD?) 来自静态代码。

2 个答案:

答案 0 :(得分:2)

我猜测代码的创建者从压缩数据中获取了大量文字和长度样本,可能包括可执行文件和文本,并且在大集合中找到了典型的代码长度。然后用显示的表格近似它们。然而,作者多年前去世了,所以我们永远不会知道。

您不需要启发式。完成查找匹配字符串的工作后,计算动态和静态表示的块中的位数相对非常快。然后只需选择较小的一个。或者静态的一个(如果相等)(解码得更快)。

答案 1 :(得分:1)

我不了解基本原理,但在选择静态代码长度时有少量 irrationale

在您的问题的表格中,最大静态代码编号为287,但DEFLATE specification仅允许代码285,这意味着代码长度浪费地分配给两个无效代码。 (甚至不是最长的!)它与距离代码表类似,有32个代码分配了长度,但只有30个有效。

因此,可以进行一些简单的改进,但是,如果没有对数据的一些先验知识,那么通常不可能生产出效率更高的任何东西。 "平坦"该表(没有长度超过9位的代码)将最坏情况的性能降低到每个不可压缩数据字节的1个额外位。

我认为分组背后的主要原理是,通过将组大小保持为8的倍数,可以通过查看5个最重要的位来判断代码属于哪个组,这也告诉您它的长度,以及要添加的值,立即获取代码值本身

00000 00   .. 00101 11     7 bits  + 256   -> (256..279)
00110 000  .. 10111 111    8 bits  -  48   -> (  0..144)
11000 000  .. 11000 111    8 bits  +  78   -> (280..287)
11001 0000 .. 11111 1111   9 bits  - 256   -> (144..255)

因此理论上你可以设置一个包含32个条目的查找表来快速读取代码,但这是一个不常见的情况,可能不值得优化。

只有两种情况(有一些重叠)固定霍夫曼块可能是最有效的:

  • 其中输入大小(以字节为单位)非常小,静态Huffman可以比未压缩更有效,因为Uncompressed使用32位头,而Fixed Huffman只需要7位页脚,加上1位潜在开销每个字节。

  • 在输出大小非常小的情况下(即小型,高度可压缩的数据),静态霍夫曼可以比动态霍夫曼更有效 - 再次因为动态霍夫曼使用一定量的空间来获得额外的头部。 (实际的最小标题大小很难计算,但我说至少64位,可能更多。)

也就是说,从开发人员的角度来看,我发现它们实际上是有用的,因为使用静态霍夫曼块实现与Deflate兼容的功能非常容易,并且从迭代中逐步改进那里有更有效的算法工作。