2011-06-10 42 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