如何在C#中计算文件的哈希值(MD5和SHA1)

13

这是我的第一个 C# 项目,我几乎是新手。我使用 openfiledialoge 选择文件并通过 GetFullPath 方法获取文件路径,并将其存储在一个名为 fpath 的变量中。我需要计算存储在 fpath 变量中的文件的哈希值。我认为可以通过 GetHashCode 完成。有人能给我一个代码片段或一个小指南吗?

4个回答

31
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 命名空间。 - Saddam Abu Ghaida
4
据我的经验,“SHA256CryptoServiceProvider” 比 “SHA256Managed” 快得多。通常可以无需修改直接替换。 - Drew Noakes

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('=');
}

11

默认情况下,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),它们将提供良好的冲突抵抗性。


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));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接