2012-11-26 83 views
12

這是我第一個C#項目,我幾乎是新手。 我使用openfiledialoge選擇文件,並通過GetFullPath方法獲取文件路徑,並將其存儲在一個名爲fpath的變量中。 我需要計算其路徑存儲在fpath變量中的文件的哈希值。我認爲這可以通過GetHashCode完成。任何人都可以給我一個片段或一個小指南?我應該如何在C#中計算文件hash(md5&SHA1)

回答

28
using (FileStream stream = File.OpenRead(file)) 
{ 
    SHA256Managed sha = new SHA256Managed(); 
    byte[] hash = sha.ComputeHash(stream); 
    return BitConverter.ToString(hash).Replace("-", String.Empty); 
} 
+1

我試過這個,我得到這個消息:無法找到類型或命名空間名稱'FileStream'。 – n1kita

+6

您需要添加system.io名稱空間 –

+3

根據我的經驗,'SHA256CryptoServiceProvider'比'SHA256Managed'快很多。這通常是替代品的下降。 –

12

下面是一些代碼,我用默認到另一個question迴應對SO

/// <summary> 
/// Gets a hash of the file using SHA1. 
/// </summary> 
/// <param name="filePath"></param> 
/// <returns></returns> 
public static string GetSHA1Hash(string filePath) 
{ 
    using (var sha1 = new SHA1CryptoServiceProvider()) 
     return GetHash(filePath, sha1); 
} 

/// <summary> 
/// Gets a hash of the file using SHA1. 
/// </summary> 
/// <param name="filePath"></param> 
/// <returns></returns> 
public static string GetSHA1Hash(Stream s) 
{ 
    using (var sha1 = new SHA1CryptoServiceProvider()) 
     return GetHash(s, sha1); 
} 

/// <summary> 
/// Gets a hash of the file using MD5. 
/// </summary> 
/// <param name="filePath"></param> 
/// <returns></returns> 
public static string GetMD5Hash(string filePath) 
{ 
    using (var md5 = new MD5CryptoServiceProvider()) 
     return GetHash(filePath, md5); 
} 

/// <summary> 
/// Gets a hash of the file using MD5. 
/// </summary> 
/// <param name="filePath"></param> 
/// <returns></returns> 
public static string GetMD5Hash(Stream s) 
{ 
    using (var md5 = new MD5CryptoServiceProvider()) 
     return GetHash(s, md5); 
} 

private static string GetHash(string filePath, HashAlgorithm hasher) 
{ 
    using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     return GetHash(fs, hasher); 
} 

private static string GetHash(Stream s, HashAlgorithm hasher) 
{ 
    var hash = hasher.ComputeHash(s); 
    var hashStr = Convert.ToBase64String(hash); 
    return hashStr.TrimEnd('='); 
} 
10

GetHashCode()方法是,僅供內部使用,檢查兩個對象引用是否實際上同一個對象。 deafult hash實現基於堆棧/堆位置,因此不會在程序運行之間確定性(或者甚至將兩個不同的引用與完全相同的數據進行比較)。所以,它不應該用於計算校驗和。

.NET有一個內置庫陣列用於此目的;它們位於System.Security.Cryptography命名空間中。你想這兩個是MD5和SHA1類:

byte[] hashBytes; 
using(var inputFileStream = File.Open(filePath)) 
{ 
    var md5 = MD5.Create(); 
    hashBytes = md5.ComputeHash(inputFileStream); 
} 

SHA1類的工作方式相同。

一句小心; MD5和SHA1都被認爲是「破碎的」,不應該用在任何需要「安全」散列的系統中。考慮在整個系統中使用SHA-256或SHA-512算法。如果你不需要一個安全的哈希,有更快的校驗和散列,如FNV-1a或MurmurHash,這將提供良好的碰撞抵抗。

3

這是一個使用C#託管庫來計算哈希的完整代碼。

using system.IO; 
using System.Security.Cryptography; 

public string GetSha1Hash(string filePath) 
{ 
    using (FileStream fs = File.OpenRead(filePath)) 
    { 
     SHA1 sha = new SHA1Managed(); 
     return BitConverter.ToString(sha.ComputeHash(fs)); 
    } 
}