Javascriptで文字列圧縮

Javascriptで文字列圧縮処理を自作したのでメモしておきます

経緯

てきとーに作ったパズルゲームでは各ステージデータを圧縮して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文字にしたら小さくなるかな?→ダメでした
圧縮については割愛

Related posts

Latest posts

Leave a Comment

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です