2013-02-15 24 views
4

我有一個程序將用於非常大的文件(當前測試數據爲250GB)。我需要能夠爲這些文件計算MD5和SHA1散列值。目前,我的代碼將數據流放入MD5.Create()。ComputeHash(數據流數據流)中,然後對SHA1執行相同操作。據我所知,這些文件以4096字節塊的形式讀取到散列函數內部的緩衝區,直到流結束。如何在不讀取同一個文件兩次的情況下計算兩個哈希值?

問題是,這樣一個接一個需要很長時間!在將新塊讀入緩衝區之前,有什麼方法可以將數據提取到緩衝區並提供緩衝區到兩種算法?

請詳細解釋,因爲我不是一個有經驗的編碼員。

+0

將其逐段讀取並將數據提供給您自己的摘要算法串聯 – sehe 2013-02-15 22:41:42

+0

檢查:http://stackoverflow.com/questions/14610850/how-to-get-file-both-md5-and-sha1-checksum- at-the-same-time-when-upload-a-new-fi(java) – PunKeel 2013-02-15 22:42:33

+0

http://stackoverflow.com/questions/7832440/is-hashalgorithm-computehash-stateful – 2013-02-15 22:43:18

回答

10

當然。您可以重複調用TransformBlock,然後在最後使用TransformFinalBlock,然後使用Hash獲取最終的哈希值。因此,像:

using (var md5 = MD5.Create()) // Or MD5Cng.Create 
using (var sha1 = SHA1.Create()) // Or SHA1Cng.Create 
using (var input = File.OpenRead("file.data")) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length()) > 0) 
    { 
     md5.TransformBlock(buffer, 0, bytesRead, buffer, 0); 
     sha1.TransformBlock(buffer, 0, bytesRead, buffer, 0); 
    } 
    // We have to call TransformFinalBlock, but we don't have any 
    // more data - just provide 0 bytes. 
    md5.TransformFinalBlock(buffer, 0, 0, buffer, 0); 
    sha1.TransformFinalBlock(buffer, 0, 0, buffer, 0); 

    byte[] md5Hash = md5.Hash; 
    byte[] sha1Hash = sha1.Hash; 
} 

MD5Cng.CreateSHA1Cng.Create通話將創建一個圍繞本地實現這可能是比MD5.CreateSHA1.Create返回實現更快的包裝,但是這將是便攜式的(例如用於PCLS)有點少。

+0

@GregS:所以它 - 修好了,謝謝。 – 2013-02-16 07:57:07

+0

完美:)我只是測試它,輸出與我的參考工具(FTK Imager)產生的散列一致,所以我都很高興! – 2013-02-16 16:45:57

+0

如果您一次計算兩個哈希值,那是因爲您希望代碼運行得很快。因此,您可能應該使用MD5Cng.Create()和SHA1Cng.Create(),假設您不支持Windows XP。請參閱:http://stackoverflow.com/questions/5341874/which-one-to-use-managed-vs-nonmanaged-hashing-algorithms – 0xdabbad00 2014-10-15 02:22:35

相關問題