多Byte文字コードの圧縮

ひょんなことから気になって調べてみたので結果を記録.

Shift-JISやEUC-JPは日本語を2Byteで表現する.同じテキストをShift-JISで表現しようが,EUC-JPで表現しようがサイズは同じになる.

けれど,多バイト文字コードのことなんて考えないASCIIな世界の人たちがLZ法のような辞書式アルゴリズムを実装した場合,1バイト単位で処理するから文字コードの差が出るのではないかとふと思った.

そういうときは論よりRun.
同じテキストを異なる文字コードで表現した際の圧縮サイズを比較してみた.

対象テキストは,みんな大好き夏目漱石「こころ」
圧縮アルゴリズムgzip (LZ77+Huffman) --bestオプション付き

元サイズ

kokoro.txt.sjis 368051 byte
kokoro.txt.euc 368051 byte

当然同じ.

圧縮後

kokoro.txt.sjis.gz 150609 byte
kokoro.txt.euc.gz 147475 byte

けっこう違う!

データをバイト単位で圧縮しているので,こういうことが起こりうる.Shift-JISやEUC-JPだったら,日本語を2Byte単位で扱ってあげればよさそう.

同じことを考える人はやはりいた.
伊藤雅, 佐藤泰司. シフトJISコード体系における日本語文書圧縮

UTF-8のような多バイトの際にはどうなんだろう?ぱっと探して見つからなかったけれど,単一言語で記述されている場合は,2Byteにマッピングして文字単位圧縮が良さそう.

こんなことしている場合ではないので今日はここまで.圧縮は初心者なので,詳しい方がいたら教えてください.


(追記)
JISやUTF-8を忘れていました.

JIS (ISO-2022-JP) は,エスケープシーケンスによって文字種の切り替えを行っているため,切り替えの数だけShift-JISやEUC-JPよりも多くなる.
UTF-8は日本語が2-4Byteで表現されるが,たいていの文字は3Byteになるため,他のメジャー日本語コードに比べて1.5倍くらいになると予想される.

元データ

kokoro.txt.sjis 368051 byte
kokoro.txt.euc 368051 byte
kokoro.txt.jis 376133 byte
kokoro.txt.utf8 551269 byte

圧縮後

kokoro.txt.sjis.gz 150609 byte
kokoro.txt.euc.gz 147475 byte
kokoro.txt.jis.gz 148234 byte
kokoro.txt.utf8.gz 169485 byte

JISがShift-JISを上回りました.理由は断言できませんが,エスケープシーケンス (1Byte) に短い符号が割り当てられていればそれで稼げるような気がします.