标签:
前言:sevenzipsharp检查密码(包括检查压缩包的有效性)的函数是SevenZipExtractor.check(), sevenzipsharp调用的是7zip的动态链接库,而且不止是7zip,其它压缩软件测试密码这个功能耗时也很久(压缩包小可以忽略,密码错误的时候速度还行,密码正确的话,会把压缩包全部解压,耗时相当于解压一个文件的时间),除了360压缩比较快,至少快几百倍,但是找不到调用的方法,如果谁有更好的解决方案,麻烦提供一下。
原来的check方法4G大小的文件大概耗时
错误的密码:www.cr173.com用时:0.19秒
正确的密码:www.he11oworld.com用时:85.98秒
方案1:我的思路是既然检测一个压缩包的解压密码,没必要把所有的文件都检测一遍,取压缩包最小的加密文件去检测就行了,4G大小的文件大概耗时
错误的密码:www.cr173.com用时:0.19秒
正确的密码:www.he11oworld.com用时:26.18秒
方案2:同样是检查一个文件,检查第一个加密文件,,4G大小的文件大概耗时
错误的密码:www.cr173.com用时:0.12秒
正确的密码:www.he11oworld.com用时:0.10秒
发现方案二是最优的,一下是具体实现的代码
定义一个全局字段,用来存取压缩包内最小的文件索引和大小
private IDictionary<int, ulong> encryptionFileInfo = null;
初始化窗体时实例化
encryptionFileInfo = new Dictionary<int, ulong>();
获取压缩包信息时,保存最小文件的索引和大小
encryptionFileInfo.Clear(); foreach (ArchiveFileInfo item in extr.ArchiveFileData) { if (item.Encrypted) { if (encryptionFileInfo.Count == 0) { encryptionFileInfo.Add(item.Index, item.Size); } ////只检测最小文件的实现方法 //else //{ // if (encryptionFileInfo.Values.ElementAt(0) > item.Size) // { // encryptionFileInfo.Clear(); // encryptionFileInfo.Add(item.Index, item.Size); // } //} } }
实现优化函数,在SevenZipExtractor.cs单元添加函数如下函数
/// <summary> /// 检查压缩包密码 /// </summary> /// <param name="minFileIndex">压缩包中加密文件索引最小的值</param> /// <returns></returns> public bool Check(int minFileIndex) { DisposedCheck(); try { InitArchiveFileData(false); var archiveStream = GetArchiveStream(true); var openCallback = GetArchiveOpenCallback(); if (!OpenArchive(archiveStream, openCallback)) { return false; } using (var aec = GetArchiveExtractCallback("", (int)_filesCount, null)) { try { uint[] u = new uint[1]; u[0] = uint.Parse(minFileIndex.ToString()); CheckedExecute( _archive.Extract(u, 1, 1, aec), SevenZipExtractionFailedException.DEFAULT_MESSAGE, aec); //CheckedExecute( // _archive.Extract(null, UInt32.MaxValue, 1, aec), // SevenZipExtractionFailedException.DEFAULT_MESSAGE, aec); } finally { FreeArchiveExtractCallback(aec); } } } catch (Exception) { return false; } finally { if (_archive != null) { _archive.Close(); } ((InStreamWrapper)_archiveStream).Dispose(); _archiveStream = null; _opened = false; } return true; }
之后就是调用了,
using (SevenZipExtractor extr = new SevenZipExtractor(tbPackagePath.Text, Convert.ToString(item["Password"]))) { if (extr.Check(index)) { tbPassword.Text = Convert.ToString(item["Password"]); memoEdit1.Text = memoEdit1.Text + "此为正确密码:" + Convert.ToString(item["Password"]) + "用时:" + (DateTime.Now - dtStartDetail).TotalMilliseconds.ToString() + "\r\n"; return; } memoEdit1.Text = memoEdit1.Text + "测试密码:" + Convert.ToString(item["Password"]) + "用时:" + (DateTime.Now - dtStartDetail).TotalMilliseconds.ToString() + "\r\n"; }
如果只用方案2可以把IDictionary<int, ulong>换成整型
标签:
原文地址:http://www.cnblogs.com/-Object/p/5376895.html