ある日、パスワードつきの ZIP ファイルを macOS 組み込みの unzip
コマンドで解凍しようとしたところ、タイトルのようなエラーになった。
今回は、その対処方法と、そもそもどういったときに起こるのかについて。
結論から先に要約してしまうと、次の通り。
- ZIP ファイルのフォーマットにはバージョンがある
unzip
コマンドがサポートしているバージョンが不足すると、このエラーになる- エラーメッセージにある "PK" とはオリジナルの ZIP アーカイバの名称からきている
- 必要なバージョンをサポートしている ZIP アーカイバを代わりに使えば解決する
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.13.5 BuildVersion: 17F77 $ unzip | head -n 2 UnZip 6.00 of 20 April 2009, by Info-ZIP. Maintained by C. Spieler. Send bug reports using http://www.info-zip.org/zip-bug.html; see README for details. $ brew info p7zip p7zip: stable 16.02 (bottled) 7-Zip (high compression file archiver) implementation https://p7zip.sourceforge.io/ /usr/local/Cellar/p7zip/16.02_1 (103 files, 4.7MB) * Poured from bottle on 2018-07-31 at 23:22:00 From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/p7zip.rb
概要
事象としては、次のように解凍できないファイルがある。 エラーメッセージでは PK のバージョンが足りない的なことを言っている。
$ unzip greet.txt.zip Archive: greet.txt.zip skipping: greet.txt need PK compat. v5.1 (can do v4.5)
上記について調べたところ ZIP ファイルのフォーマットにもバージョンがあることを知った。
また、ZIP アーカイバのオリジナル実装の名前は PKZIP という名前で、上記の "PK" はそこからきているらしい。
ようするに macOS 組み込みの unzip
コマンドが新しい ZIP フォーマット (v5.1) に対応していないってことのようだ。
解決策
解決策としては、組み込みの unzip
の代わりに p7zip
をインストールして使えば良い。
$ brew install p7zip
まあ p7zip
に限らず v5.1 フォーマットをサポートしているアーカイバなら何でも良いはず。
7za
コマンドに e
(extract) オプションをつけて解凍する。
パスワードを確認されるのでターミナルに入力する。
$ 7za e greet.txt.zip 7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,4 CPUs x64) Scanning the drive for archives: 1 file, 215 bytes (1 KiB) Extracting archive: greet.txt.zip -- Path = greet.txt.zip Type = zip Physical Size = 215 Enter password (will not be echoed): Everything is Ok Size: 13 Compressed: 215
今度はちゃんと解凍できた。
$ cat greet.txt Hello, World
unzip (6.00) で解凍できないファイルの作り方
p7zip
を使って unzip
コマンドで解凍できないファイルの作り方についても書いておく。
とりあえず圧縮前のファイルを適当に用意する。
$ echo "Hello, World" > greet.txt
あとは最近の暗号化形式を指定してパスワードつき ZIP ファイルを作る。
$ 7za a -tzip -ppassword -mem=AES256 greet.txt.zip greet.txt
これで v5.1 フォーマットの ZIP ファイルができた。
$ file greet.txt.zip greet.txt.zip: Zip archive data, at least v5.1 to extract $ unzip greet.txt.zip Archive: greet.txt.zip skipping: greet.txt need PK compat. v5.1 (can do v4.5)
ちなみに暗号化形式を指定しないで作ると v2.0 フォーマットの ZIP ファイルになった。
$ rm greet.txt.zip
$ 7za a -tzip -ppassword greet.txt.zip greet.txt
$ file greet.txt.zip
greet.txt.zip: Zip archive data, at least v2.0 to extract
これなら macOS の unzip
コマンドでも解凍できる。
$ unzip greet.txt.zip Archive: greet.txt.zip [greet.txt.zip] greet.txt password: extracting: greet.txt
いじょう。