🗜️
Javascriptで文字列圧縮
Javascriptで文字列圧縮処理を自作したのでメモしておきます
経緯
てきとーに作ったパズルゲームでは各ステージデータを圧縮してURLの後ろにくっつけてます
今までは某ライブラリで圧縮解凍していたのですがライセンス表記が見つけられず、これはアウトかもしれないと思い別のライブラリへ変更することにしました
要件は以下
- ライブラリが大きくないこと
- 圧縮後はURLにくっつけやすいこと
- 圧縮前はステージデータに使う
/^[0-9,]+$/
を満たしていればOK
色々ライブラリを漁ってみたんですが、ほとんどがパズルゲーム本体よりもサイズが大きくてダメでした
100行程度の簡潔なサンプルもあったのですが、URLエンコード対象の文字が含まれており却下
できた
というわけでサクッと自作しました
サイズは600byteくらいです
ソースはこちら
デモはこちら
今後を考えて、圧縮前の条件は/^[0-9,]+$/
ではなく/^[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
- パズルゲームの始めのステージはこんな感じです
繰り返しが多いので結構効果があります0yg,AAEV4qgqApZ5uA6pKmV12007jZ3rA050jj04igqV6404jYtA706jRjUrV447zAnUqVkZooAADV → 0000000000000000000,0000000000000000000,0000000000000000000,0000444444444440000,0000400000000050000,0000400006000040000,0000412007000340000,0000405005004440000,0000464042004440000,0000470644444440000,0000444744444440000,0000444444444440000,0000000000000000000,0000000000000000000,0000000000000000000
圧縮については割愛
もう少し汎用的に
文字種の制限を外したものも作ってみました
encodeURIComponentとかは自分でやらないとダメかもです
サイズは1kbyteくらい…もう少し整理したい…
スースはこちら
デモはこちら
解凍のロジック
圧縮後の文字列は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文字にしたら小さくなるかな?→ダメでした
圧縮については割愛
Discussion