日本語文字列を小さく保存するユニコード対応12bits文字コードJacを試作した(utf8の51~2%くらい)


UTF-8…無駄に大きなファイルになりますよね…。ASCII互換を保って作られているので当たり前といえば当たり前です。

日本語文字列の保存に不便なので小さなファイルサイズで保存できる文字コードを試作しました。(Shift-JISみたいなユニコード互換がない文字コードはNG)

名前はJacです。文字コードの詳細な定義は調べてないので、文字コードとして不完全なところが多いかと思います。

github.com/aimof/jac。実装はGoです。

ファイルサイズ

青空文庫のこころで試したところ、

規格 容量
utf8 547KB
shift-JIS 366KB
Jac 279KB

どうやって小さくしたのか

タイトルに書いたように文字を表す単位を12bitsにしました。utf8だと日本語は3Bytes、shift-Jisでも2Bytesなので、12bitsまで持ち込めばかなり容量が小さくなるだろうという目論見です。

常用漢字2000字強、ひらがな100字、記号ちょこっと、あたりが日本語で主に扱う文字なので、12bitsあればほぼほぼ足ります。上の表を見ると、おおよそ、Jac : shift-JIS : utf8 == 3 : 4 : 6になっています。

簡単な仕様

ひらがな、カタカナ、記号、常用漢字、ASCII文字は、12bits内で表せるようになってます(ハードコーディングされてます)。それ以外のUnicode文字は3Bytesを使ってのんびり記述しています。

読み書きは、3Bytes(二文字)単位で行います。

利点

  • 容量が小さい。

欠点

  • 最初から厳密に3Bytes単位で読まないとデコードできない。
  • 12bits一単位というのが、様々な他の規格と相性が悪い。
  • 文字検索機能が実装しづらい
  • 圧縮対象でない文字列を使うと容量が大きくなる。
  • ASCII互換がなく、ASCII文字が1.5Bytesに大きくなる。
  • bzip2, zstdなどの圧縮ツールと相性が悪い。

作ってみて

  • 文字コードとbit演算のいい勉強になりました。
    • 特にbit演算は12bit規格である都合上多用するので、習熟度が上がりました。
    • utf8が無駄が多い規格なのもなんとなく学べました。
  • 圧縮ツールの偉大さがわかりました。
    • 生の文字コードだと半分近いのに、bzip2で圧縮かけるとjacの方が容量が大きくなる…

まとめ

普段使っているものを自作するのはとても面白いし、学ぶことが多いですね。コメントいただければ質問には返答します。