アルゴリズム — 歴史、性能、現在の位置づけ
lha が同梱しているのは
LZHUF:1990 年代の LZ77 + 動的ハフマンで、「RAM
1 MiB の 286 での高速展開」を目指して調整され、SIMD が
まだ存在しなかった時代に書かれたものです。このページは
アルゴリズムそのもの、2026 年におけるそのコスト、そして
なぜ別のプロジェクトの単一静的バイナリがその上に
乗っかるのか、を扱います。
1. アルゴリズム
lha ファミリーの各圧縮方式(-lh0-~
-lh7-、それと -lhd- のディレク
トリヘッダ)は、共通する 2 段構成をしています:
- LZ77 風の文字列マッチング。入力中のバイト列
の繰り返しを探し、バイトをくり返す代わりに
(distance, length)の後方参照を出力しま す。LZARI / LZHUF / ZIP / gzip / zstd / lz4 / 7-zip の「LZ」はすべてこの同じアイデアで、源流は Lempel & Ziv の 1977 年の論文です。 - エントロピーコーダ。リテラルと後方参照を
ビット列に符号化します。ここで方式ごとに違いが出ます:
-lh1-— LZARI: LZ77 + 算術符号(Okumura、1988)。-lh5-— LZHUF: LZ77 + 動的ハフマン(Tagawa、1990)。デフォ ルト方式。-lh4-、-lh6-、-lh7-、-lzs-— エントロピー部分の実験的改良、または互換性 のために取っておかれた未使用符号。
静的 vs 動的ハフマン
LZHUF は静的ハフマン表をブロックごとに使います。 数 KB の入力ごとに再導出されます。この設計上の割り切り が、すべてのトレードオフを規定します:
- 利点。エンコーダはハフマン表をビットストリーム に出さなくて済みます。デコーダはブロックごとに既知 の表を持ち、ループのオーバーヘッドなしでコンパクトな 内部ループで復号できます。
- 代償。局所統計量が変化するとき(ヘッダブロック → 構造化テキスト本体 → バイナリ塊)、静的表はそのブ ロックでは局所的に最適ではありません。動的ハ フマン(deflate のデフォルトで、gzip が使う方式)で は、表をデータと一緒に持ち、適応します。これが ベンチで見える約 5 % の圧縮率差 の出どころです。
ビット・シリアルの復号ループ(そしてなぜ遅いのか)
LZHUF の復号ループはビットストリームを1 ビットずつ 読み、小さな 2× 表を辿って次のシンボルを引き当てます。こ れは原理的にシリアルで、ビット n+1 はビット n の表引きが終わるまで読めません。
ANSI C のソースコードは 1995-2003 年のままで、SIMD イン トリンジックは入っていません:
$ grep -nEi '(mmx|sse|avx|simd|__m128i|__builtin_ia32)' upstream/lha/src/*.c
$ # ヒットなし
LZ77 の length-distance コピーをベクトル化しても、展開で せいぜい 1.5–2 倍程度。ビット・シリアルのハフマン ループが天井です。展開をさらに速くするには、アルゴリズム を替えるしかなく、LZHUF をマイクロ最適化しても限界があ ります(詳しくは ベンチページ)。
2. 歴史 — 系譜
ホームページの歴史セクション が 1988-2022 の弧を詳しく語っているので、ここでは圧縮版 を:
- 1977 — LZ77。Abraham Lempel と Jacob Ziv が IEEE Transactions on Information Theory に A Universal Algorithm for Sequential Data Compression を発表。すべての現代アーカイバを規 定する、スライディング・ウィンドウ + 後方参照のアイ ディア。
- 1988 — LZARI。奥村晴彦が CPU に優しい LZ77 + 算術符号の変種を発表。LHA が借用した 286 時代 の算術コーダ。
- 1988–1989 — LHarc。吉崎英明 (Y.Tagawa)氏が LZARI を MS-DOS のアーカイバ形式 にくるむ。日本で最初に広く使われたアーカイブ形式。
- 1990 — LZHUF、本プロジェクトが同梱する形式。
Tagawa 氏が LZARI を LZ77 + 動的ハフマンへと改良し、
形式名を LHarc から LHA へ改称。圧縮方式をファイル名
末尾に埋め込む慣習(
-lh5-など)が生ま れ、今日まで続いている。 - 1991–1993 — LHA for UNIX。大木優氏 が UNIX に移植;綿貫和彦氏がコードベースを大幅書き 換え。30 年近く vendored され続けている正典 C ソー ス。
- 1993 — PKZIP 2.0 + Info-ZIPが西側の PC から LHA を駆逐。
- 1994–2010 — 日本では
.lzhがまだ主流。主要な配布サイトは LZH、Windows の SEX(自己解凍書庫)は LHA を多用、2ch 系の BBS では 2000 年代後半まで LZH の交換が普通。.lzhは 2000 年代初頭までの日本で支配的な配布形式。 - 2022 — autoconf による再始動。GitHub ユー
ザー jca02266
氏が眠っていたツリーを引き取り、現代的な autotools
ビルドを整えて LHa for UNIX 1.14i-ac20220213
とタグ付け。本リポジトリで
86094cbのコミットとして vendored して いるソースです。 - 2026 — ljh-sh/lha。
jca02266/lha@86094cbを vendored し、 主要プラットフォームごとに単一の静的バイナリとして配 布。2026 年にもなってこのプロジェクトが存在する理由は §4 にあります。
3. 性能 — 3 つの軸
数字は 効率ベンチによる、kenlm ソース 1.83 MiB のコーパス、5 試行、中央値 ± 標本標準 偏差。かいつまむと:
| ツール | レベル | 圧縮 | 展開 | 圧縮率 |
|---|---|---|---|---|
| lha | -lh5-(デフォルト) |
~50 ms | ~40 ms | 29.93 % |
| zip | -6(デフォルト) |
~62 ms | ~3 ms | 31.01 % |
| tar(無圧縮) | — | ~80 ms | ~82 ms | 149.55 % |
| tar.gz | -6(デフォルト) |
~210 ms | ~5 ms | 24.93 % |
覚えておくべき 3 つの観察
- 圧縮速度。
lhaはzip(最速、約 22 % リード)とtar.gz(最遅、約 4 倍遅い)の間。「圧縮 して保管」系のワークロード(ビルド成果物の保持、ミ ラーリング)なら、lhaは非自明な圧縮器の うちで最も安価で、生ストリームに対して約 3 倍の優位 性を保つ。 - 展開速度。
zipとtar.gzの展開は 1 桁ミリ秒;lhaは約 40 ms。ビット・シリアルのハフマ ンループが天井。絶対値はまだ小さく、CDN のネットワー ク RTT ノイズを下回る。CDN から 100 回展開し直すよ うな負荷は、アルゴリズム選択ではなく HTTP レイテンシ に支配される。 - 圧縮率。
lhaはdeflateより約 5 ポイント上(1.8 MiB の ソースで 91 KB 増)。これは 1990 年の意図的な割り切 りで、2020 年代のワークステーションで最も小さく圧縮 するのではなく、286 で高速展開することを目標に調整さ れている。
現代アルゴリズムに負ける場面 — 負けない場面
- ✗ 圧縮率では
deflateとzstdが 5–15 ポイント勝つ。 - ✗ 展開速度では
zstdがlhaの約 5–10 倍速く、lz4はさらに約 3–5 倍速い。 - ✓ 静的バイナリのフットプリント + ゼロ依存配布では
lhaの完全勝利:~150 KB でカーネルさえ あればどこでも動く。 - ✓ 「1994 年のゲームパッチがあって、他のツールでは開
けない」という場面では
lhaがデフォルト で勝つ — 開けるのがこれしか無いから。 - ✓ 長期アーカイブの安定性でも
lhaが勝 つ:35 年前のフォーマット仕様が今も実装され、読まれ ている。
ベンチページの "Deeper reading" セクションがアルゴリズム内部の理由を解説しています。短 い結論:lha は 1990 年の設計で、今日まで変わらず、天井 を決めるのはアルゴリズムであり実装ではない。
4. 現在の位置づけ — 2026 年になぜこのプロジェクトが存在するか
Vendored した jca02266/lha@86094cb のソース
は、1995-2003 年の ANSI C コードベースで、2022 年に
autotools 化を一回だけ経たものです。ljh-sh/lha はそこ
から先、たった一つのことだけをします:あらゆるプ
ラットフォーム向けに lha の単一静的バイナリ
を提供し、ユーザにコンパイラを要求しない。
2026 年、この価値提案に具体的な需要が 3 つあります:
4.1 レガシー .lzh の展開
最も分かりやすいケース:誰かが 1994 年のゲームパッチ、
2ch 系の BBS の旧添付ファイル、または 2000 年代の日本の
オープンソース書庫を持っている。現代のツールはどれも
.lzh を開けない。x eget use lha
を実行すれば、2 秒で ~/.local/bin に届き、
lha x foo.lzh で展開できる。このバイナリが
なければ、ユーザはコンパイラを入れ、1990 年代の autoconf
パッチを探し、libc が壊していないことを祈ることになる。
4.2 CI アーティファクト / CDN 配布用の単一静的バイナリ
lha はあらゆるソースツリーから単一の
.lzh 書庫を ~50–80 ms で生成し、ホストに
システム依存を求めません。CI アーティファクトの配布者
(ビルド成果物をダウンロード用にパッケージする人すべて)
にとって、これは次のような意味を持ちます:
- 最小コンテナに
libz、libcurl、libiconv、libsslなどを引き 込む必要なし。 - ~150 KB のバイナリ 1 個をベンダリング・署名・配布。
- 展開経路は Windows / macOS / Linux / BSD / 組み込み
Linux いずれでも成立 — バイナリはシステムイン
ストール無しで
~/.local/binから動く。
これは ljh-sh が各プロジェクト横断で採用している「静的 バイナリ配布規約」の中核(kenlm、upxz、そして lha)で す。具体的なパイプラインは ビルド監査を参照。
4.3 x-cmd の zuz モジュール — 直接の動機
本プロジェクトが静的ビルドとして配布されている根本の理 由がこれです。
x-cmd の
zuz モジュールは書庫ファイルのフォーマット
を自動判別し、拡張子に応じて適切なツールで透過的に圧縮
/ 展開します。tar、tar.gz、
tar.bz2、tar.xz、
zip、7z、rar、
lha 等に対応します。ただし、1 つのアーキ
テクチャ上の鉄則があります:
フォーマット専用のツールを同梱しない。常にシステム インストール済みのバイナリを起動する。
この問題は
x-cmd
issue #131(2024 年 12 月)に上がりました:ユーザが
zuz に LHA/LZH サポートを求めているが、
x-cmd が現状サポートするどの可搬パッケージシステムも
lha を提供していない。スレッドは次のよう
に進みます:
- 2024 年 12 月:メンテナ(edwinjhlee)が、v0.5.1 で
7z ベースの展開フォールバックを出荷したと
述べる(ユーザが
lhaまたはlhasaをインストール済みであれば動作)。 - 2025 年 1 月:パッケージ化された
lhaモ ジュールが出るまで、x install lhaを 暫定策として案内。 - 2026 年 7 月:メンテナが
落とし所
を示す:
zuzが本リポジトリ のリリース成果物を惰性ダウンロードし、lha未インストールのシステムでもx uz foo.lhaが動くようにする。
つまり、zuz ユーザにとっての主な導入経路
は:
x uz foo.lha
# zuz が .lha を検出、PATH に lha がない、
# フォールバック:eget ljh-sh/lha --to ~/.local/bin/lha
# その後:~/.local/bin/lha x foo.lha
Homebrew ではない。apt でもない。各ディストロのパッケー ジでもない。既定の静的インストール — 特権 インストール不要、tap 不要、ビルドチェーン不要、x-cmd サポートのすべてのプラットフォームで動く。このプロジェ クトが存在する理由は、まさにこの「既定の静的インス トール能力」を提供することだけです。
x-cmd ユーザで、lha の入っていない環境で
x uz foo.lha を実行したなら、あなたはこの
バイナリを使っています。x-cmd を使ったことがなく、単
に .lzh を開きたいだけの場合でも、このバ
イナリを使っています — 同じ成果物、同じリリース、
同じ vendored ソース。
4.4 このプロジェクトが「無いもの」
境界を正直に:
- ではないアルゴリズムのアップグレード。tANS 移植も、LZMA-lha 変種も、LZH 向け tANS 形式も、こ こには存在しない。Vendored された 1.14i はそのまま 維持する。
- ではない
tar.gz、zip、zstdの置き換え。ベンチ がどの場面でどれを使うべきかを明示している。 - ではないLZH 復権の合図。このバイナリが存在す
る唯一の理由は、フォーマット自体の長寿;あなたのワー
クフローが 2010 年以降に始まったなら、
.lzhは手元にはないはず。
5. まとめ
経験則:
| 気にする軸が… | 選ぶもの |
|---|---|
1994 年の .lzh を開く |
lha(このバイナリ) |
| クローズドシステムでの単一静的バイナリ | lha(~150 KB、ゼロ依存) |
zuz 風の自動判別 |
lha(ljh-sh/lha から惰性取得) |
| ロングテール CDN で最小サイズ | tar.gz -9 または zstd |
| マイクロ秒オーダーの展開 | lz4 または zstd |
このページが存在する理由は、「このバイナリとは何か」 と「なぜ存在するのか」を 1 か所にまとめるため & mdash; 歴史、 ベンチ、 ビルド監査、 FAQ に分散させないため。