ZIP (ファイルフォーマット)

概要

ZIPファイルフォーマット（以下ZIPフォーマット、またはZIP）は複数のファイルを一つのファイルとしてまとめて取り扱うアーカイブフォーマットであり、1つ以上のファイルが格納されているものである。必要に応じて各種ある圧縮アルゴリズムを選択・使用し、ファイルサイズを圧縮して格納することも可能である。
ZIPフォーマットは1989年にフィル・カッツが考案したもので、トム・ヘンダーソンが考案したそれまでのARCフォーマットに置き換わるものとして、PKWAREのPKZIPユーティリティ
に実装された。
ZIPフォーマットは現在多くのユーティリティによってサポートされている（ファイルアーカイバのリストを参照）。オペレーティングシステムでのサポートとしては、マイクロソフトがWindows 98以降の各バージョンに「圧縮フォルダー」という名前でZIPの機能を組み込んでいるほか、アップルもMac OS X v10.3以降に他の圧縮フォーマットも含めてZIPの機能を組み込んでいる。
ZIPファイルは一般的に ".zip" か ".ZIP" といった拡張子が付けられる。MIMEタイプはapplication/zip。ZIPフォーマットは、圧縮伸長を主目的としない多くのアプリケーションでも使用されているが、その際、拡張子には個々のアプリケーション固有に ".zip" とは異なる名前が用いられていることが多い。例えば、Java Archiveの拡張子は ".jar"であるが、このフォーマットの実態はZIPフォーマットである。他の具体例については「#ソフトにおける固有の拡張子」節を参照のこと。

歴史

"zip" （「速さ」を意味する） という名前はフィル・カッツの友人であるロバート・マホーニーの提案によるものであり、従来から有るARCやその他の圧縮フォーマットの圧縮時間よりも、自分たちのプロダクトの方が速いということをほのめかすという意図を持っていた。
ZIPファイルフォーマット仕様は、PKZIP0.9のパッケージに同梱されていた "APPNOTE.TXT" で初めて公開された。
ZIPフォーマットはオープンフォーマットとしてパブリックドメインでリリースされたものであり、ZIPフォーマットは誰しもが自由に利用でき、個人、団体、組織、あらゆる形態の利用において法的にもモラル的にも全くは制約はない。
PKWAREもまた基本フォーマットをパブリックドメインとしており、誰でもZIPファイルを扱うアプリケーションを開発することができる。同じ見解がFLOSS Info-ZIPバージョンのプロダクトに付属するUNIX/LINUXドキュメント内でも見られる。そのドキュメントではzipファイルフォーマット、圧縮フォーマット、.ZIPの拡張子やファイルフォーマットへの小さな変更をパブリックドメインに置いたフィル・カッツへの感謝の念を示している。

起源

ZIPファイルフォーマットはPKWAREのフィル・カッツが考案し、PKZIPで実装された。ちなみにカッツは以前に「PKXARC」なるアーカイブ・ユーティリティーを公開していたが、システム・エンハンス・アソシエイツ社のARCというユーティリティの著作権を著しく侵害しているとして民事訴訟を起こされている。

よく似た名前のフォーマット

名前の一部に "zip" という名前を使った標準化仕様やフォーマットがたくさんある。フィル・カッツはどんなアーカイブ種別でも "zip" という名前を使って良いと表明した。同じDeflate圧縮アルゴリズムを使用していながら、ヘッダー・フッターの異なる物としては、gzip (RFC 1952) や zlib (RFC 1950) などがある。その他、よく似た名前の異なるファイルフォーマットや圧縮アルゴリズムとして7z、bzip2、rzipなどがある。

標準化

2010年4月ISO/IEC JTC 1で、ZIP互換のISO / IECの国際標準フォーマットを作成するために開始されるプロジェクトを決めるための投票が行われた。「ドキュメントパッケージング」という表題で提案されたプロジェクトはOpenDocument、Office Open XMLやEPUBを含む既存の標準規格の利用に適したZIP互換の最小圧縮アーカイブフォーマットと考えられる。
現在のZIPフォーマットはオープンフォーマットの要求仕様にあわないことがある。それは目に見える形で公開されたコミュニティ駆動開発を通して開発されていないからである。オープンな産業機構や標準化団体が賛同してメンテナンスされているものでもない。現在の ZIP フォーマットの一部は フリー なファイルフォーマットの要求仕様にあっていない。誰もが ZIP フォーマットを、如何なる目的であっても金銭的な負担がなく利用できるようにするため、著作権、特許、商標などの制約がない。  PKWARE サイトにある最新の資料は、著作権表示があるが、フォーマット仕様とその機能拡張がパブリックドメインに置かれていることを認めている。

技術的な情報

ZIPは複数のファイルを格納するシンプルなアーカイブフォーマットである。圧縮はzipアーカイブのオプションであり、圧縮が行われる場合はファイル単位に圧縮される。
ZIPは、データの破損に備えて優れた保護機構を提供するため、32ビットのCRCアルゴリズムを利用し、またアーカイブのディレクトリ構造を2箇所に含んでいる。

構造

ZIPファイルはファイルの最後に置かれるセントラルディレクトリの終端レコード（EOCD）の存在によって正しく認識される。この仕組みにより、新たなファイルを追加することが容易である。ZIPファイルに格納されているエントリ（ファイルまたはディレクトリ）数がゼロで無い場合、格納されている各エントリの名前、エントリに関するその他のメタデータ、ZIPファイル内でエントリデータが位置するオフセットが、セントラルディレクトリエントリに記載される。これにより、ファイルリストを参照するためにアーカイブ全体を読み込む必要がないため、アーカイブのファイルリストを比較的速く表示することが可能である。また冗長性の確保のため、各エントリも、エントリ情報をローカルファイルヘッダとして保持している。zipファイルが追加されることもあるため、ファイルの最後にあるセントラルディレクトリに載っているファイルだけが、正しいファイルである。セントラルディレクトリが、いくつかのファイルは削除された、あるい更新された、と宣言していることもありうるため、ZIPファイル全体を検索してローカルファイルヘッダを探しても、正しい情報は得られない（ただし、アーカイブが破損している場合は、そのような探索は役に立つだろう）。
セントラルディレクトリ内でのファイルエントリの順番は、アーカイブの中での実際のファイルエントリの順番と同じである必要はない。
ZIPファイル内のそれぞれのエントリは、ローカルファイルヘッダ（コメント、ファイルサイズやファイル名などの情報を含む）と、オプションの 「拡張」 データフィールドと、ファイルデータそのもの（圧縮されたり暗号化されている場合もある）で構成されている。「拡張」フィールドは、ZIP64フォーマット、WinZip互換のAES暗号化、ファイル属性やより詳細なNTFSやUnixファイルのタイムスタンプをサポートするために使用される。その他にも「拡張」フィールドを使用して機能拡張することが可能。認識しない拡張フィールドを無視するための機能をZIPツールに組み込む必要がある。
ZIPフォーマットはファイル内の様々な構造を表すために、特定の4バイトの「シグネチャ」を使用する。それぞれのファイルエントリは、ある特定のシグネチャによって目印が付けられる。セントラルディレクトリの終端レコードは、それ用のシグネチャでマークされ、セントラルディレクトリ内の各エントリは別の特定の4バイトシグネチャによって目印が付けられる。
ZIPの仕様にはBOFもしくはEOFといった目印がない。慣例として、ZIPファイルの最初にはZIPエントリが置かれ、そのシグネチャによって簡単にそれとわかる。しかし、ZIPの仕様においては、ZIPエントリで始まる必要はなく、特に、自己解凍型のアーカイブは、実行可能なファイルヘッダで始まる。
ZIPアーカイブを正しく読み込むには、まず初めにセントラルディレクトリの終端レコードのシグネチャを探し、次に、適宜、他のセントラルレコードを探索する必要がある。ファイルチャンクが開始する場所を特定するのはセントラルディレクトリのみであるため、ZIPファイルの頭からエントリを検査すべきではない。ZIPフォーマットは、チャンク間に他のデータを含めることや、シグネチャと同じ4バイト列を含むようなデータを禁止していないため、そのようなスキャンは誤検出（フォールス・ポジティブ）を起こすだろう。  ただし、破損したZIPアーカイブからデータを修復するためのツールは、ローカルヘッダシグネチャを探索するのが普通である。この場合、ファイルチャンクの後ろにファイルチャンクの圧縮サイズが格納されることが、シーケンシャルな処理を困難にしている。
また ZIPの仕様では、複数のファイルシステムにまたがって分散したアーカイブを扱うこともサポートしている。もともとは、複数の1.44MBフロッピーディスク にまたがった大きなzipファイルの格納を目的としていた。現在この機能は、ZIPアーカイブを分割してメールなどで送ったり、リムーバブルメディアで持ち運ぶのに使用されている。
DOSのFATファイルシステムは2秒単位でタイムスタンプを保持し、ZIPファイルレコードはこれを模倣している。結果として、ZIPアーカイブ内にあるファイルのタイムスタンプも2秒単位で丸められる。但し、より正確なタイムスタンプを格納するために拡張フィールドを使用することができる。なお、ZIPフォーマットにはタイムゾーンという概念がないため、タイムスタンプが意味を持つのは、作成されたタイムゾーンを知っている場合だけである。
2007年9月にPKZIPは、UTF-8のファイル名を格納するための仕組みを含むZIP仕様のリビジョンをリリースした。それは最終的にZIPに対するユニコード互換を追加するものである。

圧縮メソッド

現在のZIPファイルフォーマット仕様では次のメソッドの詳細が記載されている。stored（無圧縮）、Shrunk、Reduced（メソッド 1-4）、Imploded、Tokenizing、Deflated、Deflate64、BZIP2、LZMA (EFS)、WavPack、PPMd。最も一般的な圧縮メソッドはDEFLATEでIETF RFC 1951に記載されている。
圧縮メソッドに挙げられていても、PKWARE Data Compression Library (DCL) Imploding (old IBM TERSE), IBM TERSE (new), IBM LZ77 z Architecture (PFS) の仕様の詳細は記載されていない。

暗号化

ZIPはシンプルなパスワードベースの共通鍵暗号をサポートすると仕様に記載されている。但し、重大な脆弱性があることが知られている。特に、既知平文攻撃に対して脆弱性があり、貧弱なランダム数生成器の実装によってさらに安全性が低くなる場合もある。
バージョン5.2以降の.ZIPファイルフォーマット仕様には、圧縮 と 暗号化 (例えば AES) を含む新しい機能のメソッドが追加されている、と記載されている。WinZipはAESベースの標準規格を使用し、それは7-Zip、XCeedやDotNetZipでも使用されている。しかし、ベンダによっては他のフォーマットを使用するものである PKZIP また、SecureZIP は RC2, RC4, DES, Triple DES 暗号メソッド, 電子証明書ベースの暗号 / 認証 (X.509) やアーカイブヘッダ暗号化をサポートする。

ZIP64

オリジナルのZIPフォーマットは、ZIPアーカイブ内のエントリに 65535 の制限があるのと同様に、様々なサイズ（ファイルの圧縮/非圧縮サイズ、アーカイブの合計サイズ）に4 GiBの制限があった。仕様のバージョン4.5（それは特定ツールのバージョン4.5と同じではない） では、PKWAREはこういった制限を回避するために16 EiB（2⁶⁴ バイト）まで増加させた "ZIP64" フォーマット拡張を導入した。ZIP64サポートは新規に発生したものである。例えば、Windows XPのファイルエクスプローラーはZIP64をサポートしないが、 Windows Vistaのエクスプローラーではサポートする。同様にDotNetZipやPerlのIO::Compress::Zip、PythonのzipfileのようなライブラリはZIP64をサポートする。Javaの組み込みモジュールjava.util.zipは 2010年9月現在ではサポートしていない。今後、OpenJDKに追加されてJava 7への同梱を予定している。

長所と短所

ZIPファイルのようにファイルを分割して圧縮するとランダムアクセスが可能である。他のデータを読み込むことなく個々のファイルを取り出すことができる。DEFLATE圧縮の可能性を限定するときでさえ、それぞれのファイルのために違う辞書圧縮を利用するとアーカイブ全体のサイズをより小さくできることがある。
この圧縮の手法は一般的に小さなファイルが大量にあるときのアーカイブとしては適切ではない。ZIPアーカイブフォーマットでは、個々のエントリに関する情報を持つメタデータは圧縮しない。これは、特に個々のエントリのサイズを小さくして、そのエントリ向けのメタデータのサイズを扱うようにアーカイブ可能な最大圧縮比率を設けて制限されているためである。
別の手法としては 圧縮されたtarアーカイブ（.tar.gz または .tgz） が使用される。
それはファイルデータとメタデータがgzipで圧縮される1つの単位として圧縮される。この手法の欠点はランダムアクセスの効率が悪くなってしまうことである。

ZIPと他のファイルフォーマットとの組み合わせ

ZIPファイルフォーマットでは、セントラルディレクトリの後（ファイルの末尾）に、、65,535バイト以下のデータを入れることのできるコメント欄がある。また、セントラルディレクトリがアーカイブ内の各ファイルの開始位置を表すオフセットを指定しているため、最初のエントリがオフセットゼロの位置から開始していなくてもよい。（gzipのようないくつかのツールでは、ファイルエントリがオフセットゼロで始まらないようなZIPファイルを処理できないが。）つまり、ZIPアーカイブの前や後に任意のデータを配置しても、ZIPアプリケーションはそのアーカイブを読み込むことができる。
この事実を利用すると、ZIPアーカイブとしても、別のフォーマットとしても扱えるようなファイルを作成することができる。ただし、別のフォーマットでは、ファイルの最初か末尾かあるいは中ほどに任意のデータを配置できる必要がある。WinZipやDotNetZipがサポートするSelf-extracting archives (SFX) はこの利点を活用している。そういったファイルはPKZIP AppNote.txtの仕様に準拠した.exeファイルであり、規格に準拠したzipツールやライブラリで読み込むことができる。
ZIPフォーマットやZIPの亜種であるJARフォーマットが持つこのような特性は、一見普通のファイルに見えるが、コンピューター内部に害を及ぼすJavaクラスを隠すことに悪用できてしまう。例えば、ウェブにアップロードされるGIFイメージがある。これはGIFARと呼ばれる手法で、Facebookのようなウェブアプリケーションに対して効率的な攻撃として知られている。

実装

多くのZIPツールとZIPライブラリは様々なプログラミング環境の上で利用できる。ライセンスは商用やオープンソースのものがある。例えば、WinZipはWindows上で動作する有名なZIPツールである。他にも様々なプラットホームでWinRAR、IZarc、Info-ZIP、7-Zip、PeaZipやDotNetZip等が利用できる。これらのツールのいくつかはライブラリ、またはプログラミングインタフェースを持つ。
オープンソースで開発されているライブラリの例としてはGNUプロジェクトのgzipやInfo-ZIPがある。JavaではJava Platform, Standard Editionに標準的なzipファイルを扱う "java.util.zip" パッケージがある。Zip64Fileライブラリは特別に4GBを超える巨大なファイルをサポートして、ランダムアクセスを使用してZIPファイルを扱う。Apache AntツールにはApache Software Licenseでより完全なツールが実装されている。
.NETアプリケーションでは、.NET Framework 4.5で追加されたSystem.IO.Compression名前空間のZipArchiveクラスやZipFileクラスなどが使用できる。それ以前の場合、Microsoft Public License  でソースとバイナリが利用できる DotNetZipと呼ばれる無償のオープンソースライブラリがある。従来のパスワードを用いたZIP暗号化、WinZip互換のAES暗号化、ユニコード、ZIP64、コメント、分割アーカイブ、自己展開アーカイブといった多くのZIP機能をサポートする。Microsoft .NET 3.5 ランタイムライブラリはZIPフォーマットをサポートするクラスSystem.IO.Packaging.Packageを含む。主としてISO/IEC国際標準Open Packaging Conventionsを使用するドキュメントフォーマットのために設計されている。
ZIPフォーマットのInfo-ZIP実装は、ユーザやグループID、ファイルパーミッション、シンボリックリンクのようなUnixファイルシステムの機能のサポートを追加する。Apache Antの実装はUnixパーミッションが事前に定義されたファイルを作成できる範囲に対して注意を払っている。Info-ZIPの実装もZIP圧縮フォーマットに組み込まれたエラー訂正機能の使用方法が分かっている。（IZarcのような）一部のプログラムはエラーがあるファイルの処理中に失敗する可能性がある。
また Info-ZIP WindowsツールもNTFSファイルシステムパーミッションをサポートする。展開時にNTFSパーミッションをUnixパーミッションへ、もしくはその逆へ変換しようとする。これは潜在的な意図しない結果をもたらすことがある。例として、NTFSボリューム上で実行権限を付けて作成された.exeファイルは拒否されることなどが挙げられる。

Windows 圧縮フォルダー

Windowsでは、Windows 98のためにリリースされたPlus!パック以降、エクスプローラーからZIP形式の圧縮と展開をサポートしている。マイクロソフトはこの機能を「圧縮フォルダー」と呼んでいる。圧縮フォルダーはZIPの機能を全てサポートしているわけではなく、例えばWindows 10ではAES暗号化、分割アーカイブ、パスワードを付き圧縮などが行えない。また圧縮時にはシステムロケールが日本語に設定されたWindowsではファイル名にMicrosoftコードページ932を使用している。（Windows NT系の内部文字コード及びファイルシステムの文字コードはUnicodeであるが、互換性のためにMicrosoftコードページ932に変換している。変換できない文字が含まれるファイル名は圧縮できない。）展開時はhotfixを適用したWindows 7もしくはWindows 8以降でUTF-8に対応したため、ファイル名がMicrosoftコードページ932とUTF-8のどちらであっても問題なく展開できる。macOSのFinderでは原則として圧縮・展開ともにUTF-8を想定しているため、macOSで作成したZIPファイルはhotfixを適用したWindows 7以降であればで問題なく展開できるが、逆にWindowsで作成したZIPファイルをmacOSで展開するとファイル名によっては文字化けもしくはエラーとなる。（これはファイル名の話でファイルの内容には影響しない。）

強力な暗号化についての議論

2003年に WinZip 9.0パブリックベータをリリースしたとき、WinZipは独自のAES-256暗号を導入した。それは違うファイルフォーマットを用いた新たな仕様としてドキュメントに記載された。暗号の標準規格は プロプライエタリ では無いが、 PKWARE は2001年以降、PKZIP 5.0や6.0では使用されていた強力な暗号化仕様 (SES) を含めるようにAPPNOTE.TXTを更新しなかった。WinZipの技術コンサルタント Kevin Kearneyやスタッフイット プロダクトマネージャ Mathew CovingtonはSESを差し控えるようにPKWAREを非難。これに対し、PKZIPチーフ技術オフィサーのJim Petersonは承認に基づく暗号化規格はまだ完全ではないと主張。しかし、バージョン 4.5の頃（PKWARE の FTP サイトで確認できる）に公開された最新のAPPNOTE.TXTには、SESだけではなく、同時期に存在したPKZIPプロダクトで作成された.ZIPファイルが用いたDeflate64、DCL Implode、BZip2も除外された。
この欠点を克服するためにPentaZipのような同時期に存在したプロダクトは違うファイルフォーマットにZIPアーカイブを暗号化する強力なZIP暗号化を実装した。
また別の議論では、PKWAREは2003年7月16日に安全な.ZIPファイルを作成するために強力な暗号と.ZIPを組み合わせるための方法を記載した特許を適用した。
結局PKWAREとWinZipはお互いのプロダクトをサポートすることに同意した。2004年1月21日にPKWAREはWinZipベースのAES互換フォーマットをサポートするとアナウンスした。WinZipベータの次のバージョンではSESベースのZIPファイルのサポートが行われた。PKWAREは最終的にSESを記載した.ZIPファイルフォーマット仕様のバージョン 5.2を公式にリリースした。フリーソフトウェア プロジェクト 7-Zipも（そのPOSIX 移植された p7zip が行うことで）ZIPファイルのAESをサポートしている。