2013-07-26 36 views
19

我有一個Web應用程序(rails on ruby​​),它發送一些YAML作爲隱藏輸入字段的值。在紅寶石中壓縮大字符串

現在我想減少發送到瀏覽器的文本的大小。什麼是無損壓縮的最有效形式,可以通過最小的數據發送?我可以在服務器端承擔額外的壓縮和解壓成本。

回答

47

你可以使用紅寶石核心zlib的實施中/解flate數據:

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" 

你應該使用Base64編碼的壓縮數據,使其打印:

require 'base64' 
encoded_data = Base64.encode64 compressed_data 
#=> "eJwrzs9NVcjJz0tXqEzMzVEoLinKzEsvHhUcFRwVHBUcFRwVHBUcFUQVBACz\nRyWm\n" 

後來,在客戶端,您可以使用pako(一個zlib端口到javascript)來獲取數據。 This answer可能會幫助你實現JS部分。

爲了給你如何有效的,這是一個想法,這裏的例子串的大小:在客戶端上壓縮和膨脹在服務器上時

data.size   # 2100 
compressed_data.size # 48 
encoded_data.size # 66 

也是一樣,反之亦然。

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

免責聲明:

  • 紅寶石zlib的實施應該是與PAKO實現兼容。但我沒有嘗試過。
  • 關於字符串大小的數字有點欺騙。 Zlib在這裏真的很有效,因爲這個字符串重複很多。現實生活中的數據通常不會重複。
+2

它接縫我已經倒數了這個意外前幾天,因爲我不記得這樣做。如果你願意的話,做一個編輯,這樣我就可以收回我意外的投票:( – Krule

+2

@Krule謝謝你的好。首先,我不確定我是否找到了有用的更新,但後來我偶然發現了pako,是一個比zlib好得多的zlib js庫,所以感謝提醒我再次看看我的答案,我實際上可以改進它:) – tessi

+4

請注意'Zlib :: Deflate.deflate'的輸出與格式不兼容'gzip'命令行實用程序生成並且不會被'gunzip'接受,它需要壓縮內容之前的一些頭數據。如果你想用'gunzip'讀取輸出,下面的代碼將會很有用:'Zlib :: Deflate.new(nil,31).deflate(data,Zlib :: FINISH)' – Guss