我正在使用ZipArchive在iOS应用程序中提取zip文件,但我想知道在打开文件之前是否受密码保护,以便我可以将密码传递给UnZipOpenFile函数。
答案 0 :(得分:4)
zip文件的密码不在标题中记录 它记录在zip
中的单个文件条目中所以你需要检查zip中的所有文件
将此功能添加到ZipArchive
-(BOOL) UnzipIsEncrypted {
int ret = unzGoToFirstFile( _unzFile );
if (ret == UNZ_OK) {
do {
ret = unzOpenCurrentFile( _unzFile );
if( ret!=UNZ_OK ) {
return NO;
}
unz_file_info fileInfo ={0};
ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret!= UNZ_OK) {
return NO;
}
else if((fileInfo.flag & 1) == 1) {
return YES;
}
unzCloseCurrentFile( _unzFile );
ret = unzGoToNextFile( _unzFile );
} while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE );
}
return NO;
}
答案 1 :(得分:3)
实际上我在zipArchive中找不到检测文件是否加密的功能,所以我检查了文件头以检查它是否受密码保护,如下面的链接所示:
http://secureartisan.wordpress.com/2008/11/04/analysis-of-encrypted-zip-files/
-(BOOL) IsEncrypted:(NSString*)path
{
NSData* fileData = [NSData dataWithContentsOfFile:path];
NSData* generalBitFlag = [fileData subdataWithRange:NSMakeRange(6, 2)];
NSString* genralBitFlgStr = [generalBitFlag description];
if ([genralBitFlgStr characterAtIndex:2]!='0')
{
return true;
}
else
{
return false;
}
}
全部谢谢
答案 2 :(得分:2)
我自己没有使用ZipArchive,但是通过查看代码,可以首先使用UnzipOpenFile
变体而无需密码参数,并尝试调用UnzipFileTo
。如果失败,则重新打开,但输入密码并再次致电UnzipFileTo
。这样做的问题是您将无法区分无效的zip文件和使用无效的密码。
如果您确实需要知道文件是否已加密,您可以自己添加功能(未经测试的代码):
将其添加到minizip中的unzip.c
:
extern int ZEXPORT unzIsEncrypted (file)
unzFile file;
{
return ((unz_s*)file)->encrypted;
}
这到unzip.h
:
extern int ZEXPORT unzIsEncrypted OF((unzFile file));
这到ZipArchive.mm
:
- (BOOL)ZipIsEncrypted {
return unzIsEncrypted(_unzFile);
}
这到ZipArchive.h
:
- (BOOL)ZipIsEncrypted;
在致电UnzipFileTo
后使用它。
答案 3 :(得分:1)
我解压缩了超过50mb的加密文件,因此在NSData中加载完整文件对我来说是个问题。 如此修改的答案和 我用过这个:
-(BOOL) IsEncrypted:(NSString*)path
{
NSInteger chunkSize = 1024 //Read 1KB chunks.
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
NSData *fileData = [handle readDataOfLength:chunkSize];
NSData* generalBitFlag = [fileData subdataWithRange:NSMakeRange(6, 2)];
NSString* genralBitFlgStr = [generalBitFlag description];
if ([genralBitFlgStr characterAtIndex:2]!='0')
{
return true;
}
else
{
return false;
}
}