13

This is my first C# project and I'm almost newbie. I use openfiledialoge for selecting file and get the filepath by GetFullPath method and store it in a variable called for example fpath. I need to calculate the hash of the file that its path is stored in fpath variable.I think it can be done via GetHashCode. Can anybody give me a snippet or a little guide?

4

4 回答 4

31
using (FileStream stream = File.OpenRead(file))
{
    SHA256Managed sha = new SHA256Managed();
    byte[] hash = sha.ComputeHash(stream);
    return BitConverter.ToString(hash).Replace("-", String.Empty);
}
于 2012-11-26T16:55:54.103 回答
13

这是我用来回答关于 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('=');
}
于 2012-11-26T16:56:40.817 回答
10

默认情况下,GetHashCode() 仅供内部使用,用于检查对一个对象的两个引用是否实际上是同一个对象。默认哈希实现基于堆栈/堆位置,因此在程序运行之间不是确定性的(甚至将两个不同的引用与完全相同的数据进行比较)。因此,它不应该用于计算校验和。

.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,它们将提供良好的抗碰撞性。

于 2012-11-26T17:00:31.367 回答
4

这是使用 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));
    }
}
于 2014-03-28T22:50:02.280 回答