ZIP・7z圧縮実験室
← トップへ同じ並びを、もう一度書かない
ZIPと7zは、ファイルを小さくしてまとめるための「箱」です。箱の中でデータを小さくする方法として、ZIPではDEFLATE、7zではLZMA2がよく使われます。
● 入力はブラウザ内だけで処理最初に知っておく言葉
名前は難しく見えますが、基本は「繰り返しを見つける」「よく出るものを短く書く」の2段階です。
ABCABCABC → 最初の ABC はそのまま保存 → 残りは「3バイト前から6バイトコピー」と記録。展開するときは、この指示を逆にたどって元の文字列を完全に復元します。文章を圧縮してみる
入力をUTF-8のバイトに変え、過去に同じ並びがないか探します。繰り返しが多い文章と、短い文章・ランダムな文章を比べてみてください。
「解析する」を押すと結果を表示します。
ZIP側:DEFLATEの入口
32 KiB以内の過去から、3バイト以上の最長一致を探します。青はそのままのバイト、紫は辞書参照です。各トークンにマウスを重ねると元の文字とサイズを確認できます。
7z側:LZMA2の入口
この教材では最大1 MiBの過去を探索します。実際のLZMA2は、直近距離の再利用や文脈別の確率も利用します。各トークンにマウスを重ねると元の文字とサイズを確認できます。
圧縮ファイルができるまで
ZIPとDEFLATEは同じもの?
同じではありません。ZIPは複数ファイルと名前などをまとめるアーカイブ形式で、DEFLATEはZIPで広く使われる圧縮方式です。ZIPは保存(無圧縮)など別方式も指定できます。各ファイルを基本的に個別圧縮するため、別ファイル間の繰り返しは通常共有しません。
7zとLZMA2は同じもの?
7zもアーカイブ形式で、LZMA2はよく使われる圧縮方式です。7zは複数ファイルを連続データのように圧縮する「ソリッド圧縮」が可能で、似たファイルが多いと有利です。ただし途中の1ファイルだけを取り出すのに前方からの展開が必要になる場合があります。
DEFLATE(デフレート)は何をしている?
DEFLATEは、LZ77とハフマン符号という2つの考え方を組み合わせた、データを失わない圧縮方式です。
- LZ77:今いる場所から最大32 KiB(32×1024バイト)前までを見て、同じ並びを探します。見つけた並びは「距離」と「長さ」に置き換えます。名前のLZは考案者LempelとZiv、77は発表年の1977年を表します。
- ハフマン符号:登場回数が多い記号へ短いbit列、少ない記号へ長いbit列を割り当てます。例えばAが非常に多ければAを
0、少ない記号を10110のように表し、平均の長さを縮めます。
つまり、最初に「同じ並びを省略」し、その結果に対して「よく出る記号を短く」します。展開側は保存された符号表を読み、短い記号を戻してから、距離・長さの指示どおり過去のデータをコピーします。
LZMA2(エルゼットエムエー・ツー)は何をしている?
LZMAは Lempel–Ziv–Markov chain Algorithm の略です。DEFLATEと同様に過去の一致を利用しますが、より大きな辞書を選べ、次に現れるデータの確率も細かく予測します。LZMA2はLZMAを扱いやすく拡張し、データを複数の区切りに分けたり、圧縮しにくい部分をそのまま格納したり、並列処理しやすくした方式です。
- 文脈モデル:直前の文字や、今がリテラルか繰り返しかなど、周辺の状況ごとに「次は何が出やすいか」を学習します。
- 範囲符号化:記号ごとに固定のbit列を付ける代わりに、予測確率に応じて数値の範囲を狭めていきます。出やすい記号ほど少ない情報量で表せます。
- 大きな辞書:かなり前に出た同じ並びも参照できます。見つけやすくなる一方、設定した辞書サイズに応じて多くのメモリを使います。
このためLZMA2はDEFLATEより小さくできる場合がありますが、圧縮には一般に多くの計算時間とメモリが必要です。どんなデータでも必ず小さくなるわけではありません。
DEFLATEとLZMA2の主な違い
- 辞書:DEFLATEの参照距離は最大32 KiB。LZMA2は設定によりはるかに大きな辞書を使えます。
- 符号化:DEFLATEは記号頻度から作るハフマン符号。LZMA系は周辺の状況から確率を予測するモデルと範囲符号化を組み合わせます。
- 資源:大きい辞書は遠い繰り返しを見つけやすい反面、圧縮・展開時のメモリ使用量が増えます。
- 用途:ZIPは広い互換性と取り出しやすさ、7zは高い圧縮率を重視するときに選ばれやすい方式です。