一种有效的短文本字符串压缩算法


126

我正在寻找一种压缩小文本字符串的算法:50-1000个字节(即URL)。哪种算法对此最有效?


1
您想在哪里使用这些压缩字符串?
Gumbo

1
这是走向tinyurls存储空间还是与存储空间有关?
nik

6
我对一种用于压缩URL的算法感兴趣,最佳压缩率比运行成本更重要。对诸如tinyurls或tr.im之类的在线服务不感兴趣。我在寻找一种算法而不是一种服务。不要以为其他任何信息都可能有用...
Vasily Korolev

3
@Gumbo:“用于短字符串的文本压缩算法”足以找到算法,您为什么对知道它们的用途如此感兴趣?我确信OP将能够找到执行他想要的功能的人。
Dervin Thunk

7
@Vasily,一个小提示:每当您以“什么是最好的 XYZ?” 的形式对SO提出问题时,您的问题几乎都将获得投票赞成,因为寻求最好的结果可能会导致不必要的产品比较,甚至在最坏的情况下,甚至是火焰大战。(通常只需要很小的改动就可以避免这种情况:如果您问相同的问题,例如“请建议XYZ。”,即使是基本相同的问题,您也不会获得太多的闭幕投票!)
stakx -

Answers:


62

查看Smaz

Smaz是一个简单的压缩库,适用于压缩非常短的字符串。


17
参见github.com/antirez/smaz/blob/master/smaz.c-这是编码的一种变体,不是压缩本身(至少不是完全压缩)。他使用静态单词和字母词典。
罗伊·廷克

7
注意:这是antirez的项目。他是Redis的主要作者之一,在发布高质量的生产代码方面享有很高的声誉。
Homer6'3

7
smaz算法针对英语文本进行了优化,因此不适用于随机字符串。下面是一些样本(string:orig_size:compr_size:space_savings): ,This is the very end of it.:27:13:52%Lorem ipsum dolor sit amet:26:19:27%Llanfairpwllgwyngyll:20:17:15%,,aaaaaaaaaaaaa:13:13:0%2BTWm6WcK9AqTU:14:20:-43%XXX:3:5:-67%
mykhal

4
另请查看较低的压缩率但快速的算法shoco ed-von-schleck.github.io/shoco
Dickey Singh

将我的库Unishox添加到列表github.com/siara-cc/unishox中。它的性能优于Smaz和Shoco,并支持压缩UTF-8字符串。
阿伦

28

霍夫曼表具有静态成本,即霍夫曼表,因此我不同意这是一个不错的选择。

有一些适应性版本可以解决此问题,但是压缩率可能会受到影响。实际上,您应该问的问题是“使用哪种算法压缩具有这些特征的文本字符串”。例如,如果需要长时间重复,则简单的运行长度编码就足够了。如果可以保证仅显示英文单词,空格,标点和偶数位,那么带有预定义霍夫曼表的霍夫曼可能会产生良好的结果。

通常,Lempel-Ziv系列的算法具有很好的压缩和性能,并且存在大量的库。我会去的。

有了要压缩的信息就是URL,那么我建议您在压缩之前(使用任何容易获得的算法)将它们编码。URL遵循定义明确的模式,并且其中的某些部分是高度可预测的。通过利用这些知识,您可以将URL编入较小的内容,而Huffman编码背后的想法可以为您提供帮助。

例如,将URL转换为位流,您可以将“ http”替换为位1,并将其他任何内容替换为“ 0”,再加上实际的procotol(或使用表格获取其他常见协议,例如https, ftp,文件)。只要可以标记协议的结尾,就可以完全删除“://”。等阅读有关URL格式的内容,并思考如何将它们编成代码以减少空间。


4
如果所有文件的霍夫曼表都相同,则不是这样,如果文件彼此相似,则有意义。
finnw

1
如果您有许多类似的小文件,那说明您做错了。首先,将它们全部连接起来(就像tar一样),然后将其压缩。您将获得更好的压缩,问题不再是“ 50-1000字节”。
Daniel C. Sobral

8
@Daniel:取决于是否要随机访问压缩数据。将它们全部压缩在一起可以防止大多数压缩系统使用它。
史蒂夫·杰索普

22

我没有可用的代码,但是我一直喜欢构建大小为256 * 256个字符的2D查找表的方法(RFC 1978PPP预测器压缩协议)。要压缩字符串,您可以遍历每个字符,并使用查找表使用当前和上一个字符作为表的索引来获取“预测的”下一个字符。如果匹配,则写入单个1位,否则写入0,即为char,并使用当前char更新查询表。这种方法基本上维护了数据流中最可能出现的下一个字符的动态(原始)查找表。

您可以从零查找表开始,但是如果用每个字符对(例如英语)中最有可能的字符初始化的话,那么它很适合在很短的字符串上使用。只要用于压缩和解压缩的初始查找表相同,就无需将其发送到压缩数据中。

该算法的压缩率不高,但是在内存和CPU资源方面却非常节俭,并且还可以处理连续的数据流-解压缩器在解压缩时会维护自己的查找表副本,因此查找表调整为要压缩的数据类型。


但是,预测词与普通英语句子的表现如何?给定的示例具有非常强的冗余性,并且增益很小。
Danubian Sailor'Jan

256 * 256的查找表听起来“在存储方面节俭得令人难以置信” ...!
MikeW

@MikeW好吧,这是65 KB。
redcalx17年

@redcalx如果有65个字节,我可能已经同意!
MikeW

11

支持预设字典的任何算法/库,例如zlib

这样,您可以使用可能在输入中出现的相同类型的文本为压缩器加注。如果文件在某种程度上是相似的(例如,所有URL,所有C程序,所有StackOverflow帖子,所有ASCII美术绘图),则某些子字符串将出现在大多数或所有输入文件中。

如果在一个输入文件中多次重复相同的子字符串(例如,英文文本中的“ the”或C代码中的“ int”),则每种压缩算法都会节省空间。

但是,对于URL,某些字符串(例如“ http:// www。”,“ .com”,“ .html”,“ .aspx”通常在每个输入文件中出现一次,因此需要在文件之间共享它们以某种方式而不是每个文件压缩一次,将它们放置在预设字典中即可达到目的。


2
使用自定义词典的提示:stackoverflow.com/questions/2011653
Trenton


4

如果您在谈论实际上压缩文本而不仅仅是缩短文本,则可以使用Deflate / gzip(围绕gzip的包装器),zip适用于较小的文件和文本。其他算法对于较大的文件(例如bzip2等)非常高效。

维基百科列出了压缩时间。(寻找效率比较)

Name       | Text         | Binaries      | Raw images
-----------+--------------+---------------+-------------
7-zip      | 19% in 18.8s | 27% in  59.6s | 50% in 36.4s
bzip2      | 20% in  4.7s | 37% in  32.8s | 51% in 20.0s
rar (2.01) | 23% in 30.0s | 36% in 275.4s | 58% in 52.7s
advzip     | 24% in 21.1s | 37% in  70.6s | 57& in 41.6s
gzip       | 25% in  4.2s | 39% in  23.1s | 60% in  5.4s
zip        | 25% in  4.3s | 39% in  23.3s | 60% in  5.7s

6
他想压缩文本而不是文件。
Gumbo

3
您可以使用这些算法压缩文本和二进制文件。实际上,我们在以python运行的cms系统中使用deflate。
Ryan Christensen

C#中使用gzip字符串的示例在此处:csharphelp.com/archives4/archive689.html
Ryan Christensen

python中用于压缩字符串的zlib模块:python.org/doc/2.5.2/lib/module-zlib.html
Ryan Christensen

3
gzip(和zlib)使用deflate并增加了包装器/框架的开销。.直接deflate / LZ77(字典的开销和效率仍然取决于此类和设置的实现)可以减少收支平衡的开销。当然,这是针对几十到数百个字符的“短”字符串(为了避免扩大数据,还应该有一些指示“是否已压缩”?)。随着文本的增加,更大的额外开销也无关紧要。此处发布的数字似乎是用于大型文本文件(要运行很多秒!),而OP要求提供50-1000个宪章,相比之下非常小
user2864740 '18

2

您可能想看看Unicode的标准压缩方案

SQL Server 2008 R2在内部使用它,并且可以实现高达50%的压缩。


SCSU以UTF-16 / MB编码“压缩”非英语Unicode。如果英语基础的统一字符编码/纯老ASCII,UTF-8也'压缩' UTF-16的50%..
user2864740
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.