Javascriptで文字列圧縮
Javascriptで文字列圧縮処理を自作したのでメモしておきます
Index
経緯
てきとーに作ったパズルゲームでは各ステージデータを圧縮してURLの後ろにくっつけてます
今までは某ソフトで圧縮解凍していたのですがライセンス的にアウトかもしれないと思い変更することにしました
要件は以下
- ライブラリが大きくないこと
- 圧縮後はURLにくっつけやすいこと
- 圧縮前は
/^[0-9,]+$/
を満たしていればOK
色々ライブラリを漁ってみたんですが、ほとんどがパズルゲーム本体よりもサイズが大きくてダメでした
100行程度の簡潔なサンプルもあったのですが、URLエンコード対象の文字が含まれており却下
できた
というわけでサクッと自作しました
サイズは600byteくらいです
ソースはこちら
https://github.com/utubo/js-p-data-compressor
デモはこちら
https://utubo.github.io/js-p-data-compressor/demo.html
今後を考えて、/^[0-9a-f,]+$/
の文字列に対応させておきました
解凍のロジック
g-zA-Z
が予約記号です
2文字1組で登場しg~z=0~45の数値に変換して使います
1文字目=len
、2文字目=symbol
としたとき
- 予約記号以外はそのまま出力します
symbol
===0の場合、直前の文字をlen
回繰り返します0jg → 000
symbol
!==0の場合、出力結果のsymbol
文字前からlen
文字をコピーします12345jh → 1234534
圧縮については割愛
もう少し汎用的に
文字種の制限を外したものも作ってみました
encodeURIComponentとかは自分でやらないとダメかもです
サイズは1kbyteくらい…もう少し整理したい…
スースはこちら
https://github.com/utubo/js-cheep-compressor
デモはこちら
https://utubo.github.io/js-cheep-compressor/demo.html
解凍のロジック
圧縮後の文字列はcommands_seed
のように_
で2ブロックに分かれています
commandsは0-9a-zA-Z
のみで構成されています
2文字1組で登場し0~Z=0~61の数値に変換して使います
1文字目=symbol
、2文字目=len
としたとき
symbol
===0の場合、seedの文字をlen
文字コピーしつつ読み進めます03_abc → abc
symbol
===1の場合、seedの文字を1文字読み進めlen
回繰り返します13_a → aaa
symbol
=>2の場合、出力結果のsymbol
文字前からlen
文字をコピーします0632_abcXyz → abcXyzXy
- commands処理後、残りのseedをすべて出力します
13_aXyz → aaaXyz _ABC → ABC
だいたい解凍後の方が小さいですね!
2文字1組じゃなくて3bit+3bitで1文字にしたら小さくなるかな?→ダメでした
圧縮については割愛
Leave a Comment