2011-06-10 39 views
3

我想测试一个zip文件是否在vb.net中有特定的密码。我怎样才能创建一个功能,如check_if_zip_pass(file, pass) As Boolean在vb.net中测试zip密码的正确性

我似乎无法在.net框架中找到任何可以做到这一点的东西,除非我错过了一些非常明显的东西。

此方法不应该提取文件,如果尝试的通过有效,则只返回True,如果不通过则返回False

回答

2

使用第三方库,如DotNetZip。请记住,zipfiles中的密码应用于条目,而不是整个zip文件。所以你的测试不太合理。

WinZip可能拒绝解压zip文件的一个原因是,第一个条目被密码保护。可能是这样的,只有一些条目受密码保护,而有些则不是。可能会在不同的条目上使用不同的密码。你将不得不决定你想要做什么关于这些可能性。

一种选择是假设在zipfile中的任何加密的条目上只使用一个密码。 (这不是zip规范所要求的)在这种情况下,下面是一些示例代码来检查密码。没有解密的情况下无法检查密码。所以这段代码解密并提取到Stream.Null中。

public bool CheckZipPassword(string filename, string password) 
{ 
    bool success = false; 
    try 
    { 
     using (ZipFile zip1 = ZipFile.Read(filename)) 
     { 
      var bitBucket = System.IO.Stream.Null; 
      foreach (var e in zip1) 
      { 
       if (!e.IsDirectory && e.UsesEncryption) 
       { 
        e.ExtractWithPassword(bitBucket, password); 
       } 
      } 
     } 
     success = true;  
    } 
    catch(Ionic.Zip.BadPasswordException) { } 
    return success; 
} 

哎呀!我认为在C#中。在VB.NET,这将是:

Public Function CheckZipPassword(filename As String, password As String) As System.Boolean 
     Dim success As System.Boolean = False 
     Try 
      Using zip1 As ZipFile = ZipFile.Read(filename) 
       Dim bitBucket As System.IO.Stream = System.IO.Stream.Null 
       Dim e As ZipEntry 
       For Each e in zip1 
        If (Not e.IsDirectory) And e.UsesEncryption Then 
         e.ExtractWithPassword(bitBucket, password) 
        End If 
       Next 
      End Using 
      success = True 
     Catch ex As Ionic.Zip.BadPasswordException 
     End Try 
     Return success 
    End Function 
+0

对不起,我认为这是zip本身,因为winzip不会在没有密码的情况下解压缩它。你能提供一些代码吗? – Cyclone 2011-06-10 02:04:48

2

我用SharpZipLib在.NET中做到这一点,这里是一个link他们与解压缩密码保护的zip文件的辅助功能的wiki。以下是VB.NET帮助函数的一个副本。

Imports ICSharpCode.SharpZipLib.Core 
Imports ICSharpCode.SharpZipLib.Zip 

Public Sub ExtractZipFile(archiveFilenameIn As String, password As String, outFolder As String) 
    Dim zf As ZipFile = Nothing 
    Try 
     Dim fs As FileStream = File.OpenRead(archiveFilenameIn) 
     zf = New ZipFile(fs) 
     If Not [String].IsNullOrEmpty(password) Then ' AES encrypted entries are handled automatically 
      zf.Password = password 
     End If 
     For Each zipEntry As ZipEntry In zf 
      If Not zipEntry.IsFile Then  ' Ignore directories 
       Continue For 
      End If 
      Dim entryFileName As [String] = zipEntry.Name 
      ' to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); 
      ' Optionally match entrynames against a selection list here to skip as desired. 
      ' The unpacked length is available in the zipEntry.Size property. 

      Dim buffer As Byte() = New Byte(4095) {} ' 4K is optimum 
      Dim zipStream As Stream = zf.GetInputStream(zipEntry) 

      ' Manipulate the output filename here as desired. 
      Dim fullZipToPath As [String] = Path.Combine(outFolder, entryFileName) 
      Dim directoryName As String = Path.GetDirectoryName(fullZipToPath) 
      If directoryName.Length > 0 Then 
       Directory.CreateDirectory(directoryName) 
      End If 

      ' Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size 
      ' of the file, but does not waste memory. 
      ' The "Using" will close the stream even if an exception occurs. 
      Using streamWriter As FileStream = File.Create(fullZipToPath) 
       StreamUtils.Copy(zipStream, streamWriter, buffer) 
      End Using 
     Next 
    Finally 
     If zf IsNot Nothing Then 
      zf.IsStreamOwner = True  ' Makes close also shut the underlying stream 
      ' Ensure we release resources 
      zf.Close() 
     End If 
    End Try 
End Sub 

为了测试,你可以创建一个文件进行比较,看起来在文件之前它的拉链,并再次已解压缩(大小,日期等)之后。如果你想使用简单的测试文件,比如内含文本“TEST”的文件,你甚至可以比较内容。很多选择取决于你想测试多少和多远。

+0

请重新阅读我的问题,这不是我所需要的。 – Cyclone 2011-06-10 02:20:00

1

这样做并没有太多的内置框架。下面是你可以尝试使用SharpZipLib库的一个大杂乱的混乱:

public static bool CheckIfCorrectZipPassword(string fileName, string tempDirectory, string password) 
{ 
    byte[] buffer= new byte[2048]; 
    int n; 
    bool isValid = true; 

    using (var raw = File.Open(fileName, FileMode.Open, FileAccess.Read)) 
    { 
     using (var input = new ZipInputStream(raw)) 
     { 
      ZipEntry e; 
      while ((e = input.GetNextEntry()) != null) 
      { 
       input.Password = password; 
       if (e.IsDirectory) continue; 
       string outputPath = Path.Combine(tempDirectory, e.FileName); 

       try 
       { 
        using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite)) 
        { 
         while ((n = input.Read(buffer, 0, buffer.Length)) > 0) 
         { 
          output.Write(buffer, 0, n); 
         } 
        } 
       } 
       catch (ZipException ze) 
       { 
        if (ze.Message == "Invalid Password") 
        { 
         isValid = false; 
        } 
       } 
       finally 
       { 
        if (File.Exists(outputPath)) 
        { 
         // careful, this can throw exceptions 
         File.Delete(outputPath); 
        } 
       } 
       if (!isValid) 
       { 
        break; 
       } 
      } 
     } 
    } 
    return isValid; 
} 

C#的道歉;应该是相当简单的转换为VB.NET。

+0

我跑了一个转换器,但它没有工作。你可以提供实际的VB代码的任何方式? – Cyclone 2011-06-10 19:49:04