【问题标题】:Using a preset deflate dictionary to reduce compressed archive file size使用预设的 deflate 字典来减少压缩存档文件的大小
【发布时间】:2021-08-10 09:34:52
【问题描述】:

我有一个要求,将文本文件从一个位置发送到另一个位置。这两个位置都在我们的控制之下。内容的性质和其中可能出现的词语大体相同。这意味着,如果我将delate dictionary 保留在两个位置一次,则无需将其与文件一起发送。

过去 1 周我一直在阅读这方面的内容,并尝试了一些可用的代码,例如 this 和 this。

但是,我还是一头雾水。

我还有几个问题:

  1. 我们可以从预设的单词中生成和使用自定义的 deflate 字典吗?
  2. 我们可以在没有 deflate 字典的情况下发送文件并使用本地字典吗?
  3. 如果不是 gzip,是否有任何可以用于此目的的压缩库?

到目前为止我偶然发现的一些参考资料:

  1. https://medium.com/iecse-hashtag/huffman-coding-compression-basics-in-python-6653cdb4c476
  2. https://blog.cloudflare.com/improving-compression-with-preset-deflate-dictionary/
  3. https://www.euccas.me/zlib/#zlib_optimize_cloudflare_dict

【问题讨论】:

    标签: javascript python compression deflate lossless-compression


    【解决方案1】:

    zlib 库支持 zlib(不是 gzip)格式的字典。请参阅deflateSetDictionary() 和inflateSetDictionary()。

    字典的构造没有什么特别之处。它只是 32K 字节的字符串,您认为这些字符串会经常出现在您正在压缩的数据中。您应该将最常用的字符串放在 32K 的末尾。

    【讨论】:

      【解决方案2】:

      以下是我找到的具体答案以及示例代码。

      1.我们可以从预设的单词中生成和使用自定义的 deflate 字典吗?

      是的,这是可以做到的。 python中的一个简单示例如下:

      import zlib
      
      #Data for compression
      hello = b'hello'    
      
      #Compress with dictionary
      co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=hello)
      compress_data = co.compress(hello) + co.flush()
      

      2。我们可以在没有 deflate 字典的情况下发送文件并使用本地字典吗?

      是的,您可以只发送不带字典的数据。压缩数据在上述示例代码中的compress_data 中。但是,要解压缩,您需要在压缩过程中传递 zdict 值。解压方式示例:

      hello = b'hello'  #for passing to zdict  
      do = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=hello)
      data = do.decompress(compress_data)
      

      包含和不包含 dict 数据的完整示例代码:

      import zlib
      
      #Data for compression
      hello = b'hello'
      
      #Compression with dictionary
      co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=hello)
      compress_data = co.compress(hello) + co.flush()
      
      #Compression without dictionary
      co_nodict = zlib.compressobj(wbits=-zlib.MAX_WBITS, )
      compress_data_nodict = co_nodict.compress(hello) + co_nodict.flush()
      
      #De-compression with dictionary
      do = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=hello)
      data = do.decompress(compress_data)
      
      #print compressed output when dict used
      print(compress_data)
      
      #print compressed output when dict not used
      print(compress_data_nodict)
      
      #print decompressed output when dict used
      print(data)
      

      以上代码不适用于 unicode 数据。对于 unicode 数据,您必须执行以下操作:

      import zlib
      
      #Data for compression
      unicode_data = 'റെക്കോർഡ്'
      hello = unicode_data.encode('utf-16be')
      
      #Compression with dictionary
      co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=hello)
      compress_data = co.compress(hello) + co.flush()
      ...
      

      基于 JS 的方法参考:

      1. How to find a good/optimal dictionary for zlib 'setDictionary' when processing a given set of data?
      2. Compression of data with dictionary using zlib in node.js

      【讨论】:

        猜你喜欢
        • 2019-10-16
        • 1970-01-01
        • 1970-01-01
        • 2021-03-30
        • 1970-01-01
        • 2020-04-23
        • 2011-08-18
        • 2013-09-11
        • 1970-01-01
        相关资源
        最近更新 更多