2013-07-26 10 views
19

私は隠された入力フィールドの値としていくつかのYAMLを送るWebアプリケーション(ruby on rails)を持っています。ルビーの大きな文字列を圧縮する

今ブラウザに送信されるテキストのサイズを縮小したいと考えています。最小限のデータを送信する最も効率的なロスレス圧縮の形式は何ですか?私はサーバー側で圧縮と解凍の追加コストが発生するのは大丈夫です。

答えて

47

あなたは、DE-Flateアルゴリズムデータ/中にルビーコアに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" 

あなたはそれを印刷可能にするために圧縮されたデータをbase64でエンコードする必要があります。

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

その後クライアント側では、pako(JavaScriptのzlibポート)を使用してデータを元に戻すことができます。 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はすてきでありがとうございます最初に私は有用なアップデートを見つけたかどうかはわかりませんでしたが、 Zlib :: Zlib jsライブラリはzlibよりもはるかに優れています。私の答えをもう一度見ていただきありがとうございます。実際には改善することができます:) – tessi

+4

'Zlib :: Deflate.deflate'の出力は、 'gzip'コマンドラインユーティリティは' gunzip'によって生成され、 'gunzip'によって受け入れられないでしょう。 'gunzip'を使用して出力を読みたい場合、次のコードが役に立ちます:' Zlib :: Deflate.new(nil、31).deflate(data、Zlib :: FINISH) ' – Guss

関連する問題