[Swift]パスワード付きZipファイルを作る。
ZipArchiveを使ってパスワード付きZipファイルを作成します。
https://github.com/ZipArchive/ZipArchive
パスワード付きZipにするとパスワードを正しく入力しても解凍できない問題が発生
元々、以下リンクのZipを使おうと考えてましたが、パスワード付きにすると解凍できないという問題がありました。
https://github.com/marmelroy/Zip
以下issueは上がっているけど、解決されていない状況のようです。
https://github.com/marmelroy/Zip/issues/215
原因は、AES暗号化によるもので、AESが有効の場合は同じライブラリを使って書かれた解凍アプリケーションが必要のようです。
従って、AESを無効にすれば解決しそうですがZipにはそのオプションがないということがわかったのでZipArchiveを使うことにしました。
ZipArchiveでACE無効にする設定
使い方の例はこれ。
ace:falseにすることが肝です。
let result = SSZipArchive.createZipFile(
atPath: zipFilePath.path,
withContentsOfDirectory: raw.path,
keepParentDirectory: false,
compressionLevel: 1,
password: "password",
aes: false,
progressHandler: nil)
最初、atPathに圧縮したいフォルダパスを入れていたのでうまくいかなかった。
原因探るために、SSZipArchive.mにブレークはってデバッグしました。
わかったことは、atPathが圧縮先だということでした。
デバッグついでにざっくりソース眺めてみました。
compressionLevelに何を指定すべきなのかよくわからなかったので調べてみると、以下の設定があることが分かりました。これらconstantをswiftから使う方法はないのだろうか。
あと、これコメントが下にあるのなんでだろう。
#define Z_NO_COMPRESSION 0
#define Z_BEST_SPEED 1
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)
/* compression levels */
SSZipArchive.hを眺めてみる。ACE無効はディレクトリのみ対応している?
該当箇所はこちら。
引数違いでメソッドが並んでいます。
// Zip
// default compression level is Z_DEFAULT_COMPRESSION (from "zlib.h")
// keepParentDirectory: if YES, then unzipping will give `directoryName/fileName`. If NO, then unzipping will just give `fileName`. Default is NO.
// without password
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory;
// with optional password, default encryption is AES
// don't use AES if you need compatibility with native macOS unzip and Archive Utility
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password;
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(nullable NSString *)password;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password;
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory
withPassword:(nullable NSString *)password
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory
compressionLevel:(int)compressionLevel
password:(nullable NSString *)password
AES:(BOOL)aes
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
//suport symlink compress --file
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password keepSymlinks:(BOOL)keeplinks;
//suport symlink compress --directory
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory
compressionLevel:(int)compressionLevel
password:(nullable NSString *)password
AES:(BOOL)aes
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler
keepSymlinks:(BOOL)keeplinks;
元ファイルの指定方法は大きく分けて二つあるようだ。
withFilesAtPaths:(NSArray<NSString *> *)paths
withContentsOfDirectory:(NSString *)directoryPath
Zipの元になるものが、
・複数ファイル
・ディレクトリ
という分類みたい。
ソースを見ていると、複数ファイルを引数にとるメソッドにはACEの設定ができるものがなかった。
つまり、ACE無効にしたい場合は、ディレクトリを引数にとるパターンのものしか使えない。
ディスカッション
コメント一覧
まだ、コメントがありません