如何从文本文件创建一个MD5哈希摘要?

25

使用 C#,我想要创建一个文本文件的 MD5 哈希值。我该如何实现?

更新:感谢每个人的帮助。我最终选择以下代码 -

// Create an MD5 hash digest of a file
public string MD5HashFile(string fn)
{            
    byte[] hash = MD5.Create().ComputeHash(File.ReadAllBytes(fn));
    return BitConverter.ToString(hash).Replace("-", "");            
}

现在最好避免使用MD5,因为它已知存在漏洞。https://en.wikipedia.org/wiki/MD5 - Matthew Lock
4个回答

16

这是我目前正在使用的例程。

    using System.Security.Cryptography;

    public string HashFile(string filePath)
    {
        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            return HashFile(fs);
        }
    }

    public string HashFile( FileStream stream )
    {
        StringBuilder sb = new StringBuilder();

        if( stream != null )
        {
            stream.Seek( 0, SeekOrigin.Begin );

            MD5 md5 = MD5CryptoServiceProvider.Create();
            byte[] hash = md5.ComputeHash( stream );
            foreach( byte b in hash )
                sb.Append( b.ToString( "x2" ) );

            stream.Seek( 0, SeekOrigin.Begin );
        }

        return sb.ToString();
    }

太好了,roufamatic。它返回一个32位十六进制数吗? - Craig Schwarze
刚测试了一下这个函数,它完全符合我的需求 - 再次感谢。 - Craig Schwarze
1
如果您不需要重复使用流,当然可以删除所有代码。这曾经是一种管道的形式,以便首先对流进行哈希处理,然后进行gzip压缩。现在我主要关心哈希值,因此采用了快捷方式。 - roufamatic

11

简单明了。 filename 是你的文本文件名:

using (var md5 = MD5.Create())
{
    return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filename))).Replace("-", "");
}

4
ToBase64String不能返回我想要的结果。然而,使用BitConverter.ToString转换字节数组可以达到效果。 - Craig Schwarze

3

可以通过 GetHashCode 的重载实现,允许传递 filePath、StreamReader 或 Stream:

private static string GetHashCode(string filePath, HashAlgorithm cryptoService = null)
    => GetHashCode(fStream: new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), cryptoService);

private static string GetHashCode(StreamReader fileStreamReader, HashAlgorithm cryptoService = null)
    => GetHashCode(fileStreamReader.BaseStream, cryptoService);


/// <summary>
/// Compute hash code for file.
/// </summary>
/// <param name="fStream"></param>
/// <param name="cryptoService">This can be either MD5, SHA1, SHA256, SHA384 or SHA512</param>
/// <returns>Hash string</returns>
private static string GetHashCode(Stream fStream, HashAlgorithm cryptoService = null)
{

    // create or use the instance of the crypto service provider
    // this can be either MD5, SHA1, SHA256, SHA384 or SHA512
    using (cryptoService ??= System.Security.Cryptography.SHA512.Create())
    {
        using var tmpStream = fStream;
        var hash = cryptoService.ComputeHash(tmpStream);
        var hashString = Convert.ToBase64String(hash);
        return hashString.TrimEnd('=');
    }
} // method

使用方法:

WriteLine("Default Sha512 Hash Code   : {0}", GetHashCode(FilePath));

或:

WriteLine("MD5 Hash Code   : {0}", GetHashCode(FilePath, new MD5CryptoServiceProvider()));
WriteLine("SHA1 Hash Code  : {0}", GetHashCode(FilePath, new SHA1CryptoServiceProvider()));
WriteLine("SHA256 Hash Code: {0}", GetHashCode(FilePath, new SHA256CryptoServiceProvider()));
WriteLine("SHA384 Hash Code: {0}", GetHashCode(FilePath, new SHA384CryptoServiceProvider()));
WriteLine("SHA512 Hash Code: {0}", GetHashCode(FilePath, new SHA512CryptoServiceProvider()));

好的解决方案!我建议进行一点改进:使第二个参数可为空,即 HashAlgorithm cryptoService = null,然后加入一个默认提供程序,如下所示:using (cryptoService ??= System.Security.Cryptography.SHA512.Create()) - 或者如果您喜欢,也可以使用 MD5(但我不建议)。这将简化使用,同时保持最大的灵活性(您仍然能够添加自己选择的提供程序)。 - Matt
提示(对于需要的人):如果您需要一个StreamReader(fileStreamReader)而不是文件路径作为参数,您可以创建一个重载此函数的方式,例如 using var fileStream = fileStreamReader.BaseStream; - Matt

0
这是一个与 .NET Standard 相关的版本,它不需要将整个文件读入内存:
    private byte[] CalculateMD5OfFile(FileInfo targetFile)
    {
        byte[] hashBytes = null;
        using (var hashcalc = System.Security.Cryptography.MD5.Create())
        {
            using (FileStream inf = targetFile.OpenRead())
                hashcalc.ComputeHash(inf);
            hashBytes = hashcalc.Hash;
        }
        return hashBytes;
    }

你可以使用上面展示的方法将byte[]数组转换为字符串。另外,你可以在第三行中将"MD5"更改为SHA1、SHA256等来计算其他哈希值。

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