読者です 読者をやめる 読者になる 読者になる

リア充爆発日記

You don't even know what ria-ju really is.

JavaでDeflateしてBase64したやつをRubyでBase64してInflateできるか確認

ちょいと多めのテキストデータをサーバに送るとき、帯域を抑えたいからDeflateしてBase64して送ろう!と思ったが、バグとか基準にしているRFCが違うとかそういうのでサーバサイドであるRubyと相互変換できなかったらヤだなぁと思って試してみた。

deflate and base64encode

            String original = "リア充爆発しろ!!!!" ;

            byte[] dataByte = original.getBytes();

            System.out.println("original size:" + dataByte.length);
            Deflater def = new Deflater();
            def.setLevel(Deflater.BEST_COMPRESSION);
            def.setInput(dataByte);
            def.finish();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(dataByte.length);
            byte[]buf = new byte[1024];
            while(!def.finished()) {
                int compByte = def.deflate(buf);
                byteArrayOutputStream.write(buf, 0, compByte);
            }
            byteArrayOutputStream.close();

            byte[] compData = byteArrayOutputStream.toByteArray();

            String encoded = Base64.encodeToString(compData, Base64.DEFAULT);
            System.out.println("deflated size:" + compData.length);
            System.out.println("base64encoded size:" + encoded.length());
            System.out.println("base64:" + encoded);
original size:33
deflated size:35
base64:eNp73LzqcdOip62tzzvans/c9bhx+uOm3vd7GuEIAIHtFtM=
base64encoded size:49

今回は元の文字列が短いので逆にデータ量は多くなった。


Ruby側はirbでやった。

1.9.3-p0 :001 > require 'zlib'
 => true 
1.9.3-p0 :002 > require 'base64'
 => true 
1.9.3-p0 :003 > decoded = Base64.decode64("eNp73LzqcdOip62tzzvans/c9bhx+uOm3vd7GuEIAIHtFtM=")
 => "x\xDA{\xDC\xBC\xEAq\xD3\xA2\xA7\xAD\xAD\xCF;\xDA\x9E\xCF\xDC\xF5\xB8q\xFA\xE3\xA6\xDE\xF7{\x1A\xE1\b\x00\x81\xED\x16\xD3" 
1.9.3-p0 :004 > Zlib::Inflate.inflate(decoded).force_encoding("UTF-8")
 => "リア充爆発しろ!!!!" 


戻った。


ちなみに元データを100回繰り返すと圧縮効果は相当でる。

            int count = 100;
            StringBuilder stringBuilder = new StringBuilder();
            for(int i = count; i -->0;) {
                stringBuilder.append("リア充爆発しろ!!!!");
            }
            String original = stringBuilder.toString();
original size:3300
deflated size:64
base64:eNp73LzqcdOip62tzzvans/c9bhx+uOm3vd7GuHo8aiCUQWjCkYVjCoYVTCqYFTBqIJRBaMKRhUM
base64encoded size:90
HQUAavnqgQ==


ただ同じ文字列が単調に出現するからそうとう圧縮されたけど、普通はここまで圧縮しないと思う。

っていうか、なんでJavaのDeflateあんなに手順がいるの!