非常に前時代的な話なのですが、 ZIP ファイルにパスワードをかけたいことがあるかと思います。
その用事に対応するために、Macを利用して ZIP ファイルを作った時にパスワードをかけたのですが、なぜか解凍できなくて困ったので ここに残しておきます。
結論
MacでZIPファイルにパスワードをかける際には、zipcloakを利用せずに、ターミナルでファイルを圧縮する必要があります。
"zip -e" でやっておくのが安全です。
ただし、解凍できるパターンもあるので、もしかしたら最新のMacOSだとCRCエラーを無視して解凍するようになっているのかもしれません。
何が起こった?
"mac zip パスワード" などで検索するとzipcloakを利用する方法が上がってくるかと思います。
このzipcloakを利用して、「ファインダーで右クリックして圧縮した」zipファイルにパスワードをかけると解凍できなくなる。という問題が起こりました。
例
$ for t in a b c d e;do echo $t > $t.txt; done
選択して右クリックから圧縮
$ zipcloak アーカイブ.zip
Enter password:
Verify password:
encrypting: a.txt
zipcloak warning: Local Entry CRC does not match CD: a.txt
encrypting: b.txt
zipcloak warning: Local Entry CRC does not match CD: b.txt
encrypting: c.txt
zipcloak warning: Local Entry CRC does not match CD: c.txt
encrypting: d.txt
zipcloak warning: Local Entry CRC does not match CD: d.txt
encrypting: e.txt
zipcloak warning: Local Entry CRC does not match CD: e.txt
ただ、よくわからないのが、このテスト用のファイルだとうまく解凍できてしまうというところですね…
巷の記事では、「Local Entry CRC does not match CD」というエラーそのものが解凍不可能な条件のように書かれています。
追加で調査してみた
よくよく考えると、ディレクトリを含む場合に解凍に失敗していた気がするので、条件を変更します。
例
$ for t in a b c d e;do echo $t > $t.txt; done
$ for t in a b c d e;do echo $t > ziptest/$t.txt; done
右クリックで圧縮
$ zipcloak アーカイブ.zip
Enter password:
Verify password:
encrypting: a.txt
zipcloak warning: Local Entry CRC does not match CD: a.txt
encrypting: b.txt
zipcloak warning: Local Entry CRC does not match CD: b.txt
encrypting: c.txt
zipcloak warning: Local Entry CRC does not match CD: c.txt
encrypting: d.txt
zipcloak warning: Local Entry CRC does not match CD: d.txt
encrypting: e.txt
zipcloak warning: Local Entry CRC does not match CD: e.txt
encrypting: ziptest/
encrypting: ziptest/c.txt
zipcloak warning: Local Entry CRC does not match CD: ziptest/c.txt
encrypting: ziptest/b.txt
zipcloak warning: Local Entry CRC does not match CD: ziptest/b.txt
encrypting: ziptest/a.txt
zipcloak warning: Local Entry CRC does not match CD: ziptest/a.txt
encrypting: ziptest/e.txt
zipcloak warning: Local Entry CRC does not match CD: ziptest/e.txt
encrypting: ziptest/d.txt
zipcloak warning: Local Entry CRC does not match CD: ziptest/d.txt
これでも解凍できる…
エラーメッセージの意味を理解する
誤り訂正に利用するCRCのエラーのようですが、CDに関する情報が全く見当たらず、なんの略なのかわからないですね…
大文字2文字で略さないでほしいですね。
ZipArchiveから頑張って辿ってどうやらCentral Directoryではないかというところでアタリをつけています。
間違っていたらコメントなどでご指摘ください。
Minizip 2.8.6 by Coeur · Pull Request #509 · ZipArchive/ZipArchive · GitHub
Do not write central directory header if central directory is 0 bytes… · zlib-ng/minizip-ng@64faa25 · GitHub
ZIP (file format) - Wikipedia にもCentral Directoryの記載があるのでおそらく合っていると思うのですが、このどこからどこまでが1ファイルの領域かという部分が壊れてしまって不整合になっているということなんですかね?
ひとまず、不整合が起こる条件になってしまっているということのようです。
どう対策する
"zip -e"コマンドを使ってパスワードを付与するのが無難なようです。
例
$ zip -e archive.zip *.txt
Enter password:
Verify password:
adding: a.txt (stored 0%)
adding: b.txt (stored 0%)
adding: c.txt (stored 0%)
adding: d.txt (stored 0%)
adding: e.txt (stored 0%)
$ unzip -t archive.zip
Archive: archive.zip
[archive.zip] a.txt password:
testing: a.txt OK
testing: b.txt OK
testing: c.txt OK
testing: d.txt OK
testing: e.txt OK
No errors detected in compressed data of archive.zip.
感想
うまく解凍できたりできなかったりしてややこしいのですが、ひとまずコマンドを使っておこうと思いました。
本筋とは異なりますが、英語を大文字で略記するのはトラブルシューティングがしづらいのでやめてほしいですね…