2

我正在开发一个需要在查询字符串(特别是 GET 而不是 POST)上获取文件列表的网络应用程序,例如:

http://site.com/app?things=/stuff/things/item123,/stuff/things/item456,/stuff/things/item789

我想缩短那个字符串:

http://site.com/app?things=somekindofencoding

字符串不是很长,从 20 到 150 个字符不等。这么短的东西并不适合 GZip,但它确实有很多重复,所以压缩应该是可能的。

我不想要字符串的数据库或字典 - URL 将由与使用它的应用程序不同的应用程序构建。我想要一个可缩短此 URL 的可逆压缩。它不需要是安全的。

有没有现有的方法可以做到这一点?我在 C#/.Net 中工作,但很乐意从其他语言/堆栈中调整算法。

4

2 回答 2

1

如果您可以在 BNF 中表达数据,则可以为数据构建解析器。您可以发送 AST,而不是发送数据,其中每个节点将被标识为一个字符(或者如果您有很多不同的节点,则为多个字符)。在你的例子中

我们可以有

files : file files
      | 
file : path id
path : itemsthing
     | filesitem
     | stuffthingsitem

您可以将文件列表表示为 path[id1,id2,...,idn] 使用 0,1,2 作为路径和输入:

/stuff/things/item123,/stuff/things/item456,/stuff/things/item789
/files/item1,/files/item46,/files/item7

然后你会得到?things=2[123,456,789]1[1,46,7]

其中/stuff/things/item用表示2/files/item/用其中的1每个数字表示[...]是一个 id。所以2[123]会扩展到/stuff/things/item123

编辑该方法不必是静态的。如果您必须动态发现重复的项目,您可以使用相同的方法并在标识符和令牌之间传递映射。在这种情况下,上面的例子将是

?things=2[123,456,789]1[1,46,7]&tokens=2=/stuff/things/,1=/files/item

如果语法如此简单,当然会做得更好

?things=/stuff/things/[123,456,789]/files/item[1,46,7]

使用如此短的字符串将重复的部分压缩到小于唯一值是可能的,但很可能必须基于限制可能的值或在“压缩”时实际增加大小的风险

于 2012-06-12T09:33:42.120 回答
0

您可以尝试使用原始 deflate 的zlib(没有 zlib 或 gzip 标头和预告片)。即使在由可打印字符组成的短字符串上,它通常也会提供一些压缩,并且会寻找并利用重复的字符串。我还没有尝试过,但也可以看看smaz是否适用于您的数据。

我建议获取大量真实示例 URL,用于对可能的压缩方法进行基准测试。

于 2012-06-12T15:56:06.863 回答