压缩红宝石中的大字符串

gna*_*rsi 24 ruby compression

我有一个Web应用程序(ruby on rails),它将一些YAML作为隐藏输入字段的值发送.

现在我想减少发送到浏览器的文本的大小.在最小数据中发送的最有效的无损压缩形式是什么?我可以在服务器端产生额外的压缩和解压缩成本.

tes*_*ssi 58

您可以使用ruby核心中的zlib实现来进/出数据:

require "zlib"
data = "some long yaml string" * 100
compressed_data = Zlib::Deflate.deflate(data)
#=> "x\x9C+\xCE\xCFMU\xC8\xC9\xCFKW\xA8L\xCC\xCDQ(.)\xCA\xCCK/\x1E\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15D\x15\x04\x00\xB3G%\xA6"
Run Code Online (Sandbox Code Playgroud)

您应该对压缩数据进行base64编码以使其可打印:

require 'base64'
encoded_data = Base64.encode64 compressed_data
#=> "eJwrzs9NVcjJz0tXqEzMzVEoLinKzEsvHhUcFRwVHBUcFRwVHBUcFUQVBACz\nRyWm\n"
Run Code Online (Sandbox Code Playgroud)

稍后,在客户端,您可以使用pako(一个zlib端口到javascript)来获取数据.这个答案可能会帮助您实现JS部分.

为了让您了解这是多么有效,以下是示例字符串的大小:

data.size            # 2100
compressed_data.size #   48
encoded_data.size    #   66
Run Code Online (Sandbox Code Playgroud)

在客户端上进行压缩并在服务器上进行充气时,反之亦然.

Zlib::Inflate.inflate(Base64.decode64(encoded_data))
#=> "some long yaml stringsome long yaml str ... (shortened, as the string is long :)
Run Code Online (Sandbox Code Playgroud)

免责声明:

  • ruby zlib实现应该与pako实现兼容.但我没试过.
  • 有关字符串大小的数字有点受骗.Zlib在这里非常有效,因为字符串重复了很多.现实生活中的数据通常不会重复.

  • 请注意,`的zlib :: Deflate.deflate`的输出不与所述`gzip`命令行实用程序产生,并且不会被`gunzip`被接受的格式,这预计压缩内容之前的一些报头数据相兼容.如果你想使用`gunzip`读取输出,下面的代码将是有用的:`Zlib :: Deflate.new(nil,31).deflate(data,Zlib :: FINISH)` (6认同)
  • @Krule谢天谢地.首先我不确定我是否找到了有用的更新,但后来我偶然发现pako(似乎)是一个比zlib好得多的zlib js库.所以感谢提醒再次查看我的答案,我实际上可以改进:) (3认同)
  • 我几天前因为不记得这样做了,所以我已经对此事进行了评论.如果你愿意,做一个编辑,这样我可以收回我的意外下来投票:( (2认同)