我应该如何在C#中计算文件哈希值(md5和SHA1)

时间:2022-10-28 17:24:55

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?

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

4 个解决方案

#1


30  

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

#2


13  

Here's some code I used to respond to another question on SO

这是我用来回答关于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('=');
}

#3


10  

GetHashCode() is, by default, for internal use only, to check whether two references to an object are in fact the same object. The deafult hash implementation is based on stack/heap location and is thus not going to be deterministic between runs of the program (or even comparing two different references with exactly the same data). So, it should not be used for computing checksums.

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

.NET has an array of built-in libraries that serve this purpose; they're in the System.Security.Cryptography namespace. The two you want are the MD5 and SHA1 classes:

.NET有一系列用于此目的的内置库;它们位于System.Security.Cryptography命名空间中。你想要的两个是MD5和SHA1类:

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

The SHA1 class works the same way.

SHA1类的工作方式相同。

A word of caution; both MD5 and SHA1 are considered "broken" and should not be used in any system requiring a "secure" hash. Consider using the SHA-256 or SHA-512 algorithms in the overall system instead. If you don't need a secure hash, there are faster checksum hashes like FNV-1a or MurmurHash that will provide good collision resistance.

谨慎一点; MD5和SHA1都被视为“已损坏”,不应在任何需要“安全”哈希的系统中使用。请考虑在整个系统中使用SHA-256或SHA-512算法。如果您不需要安全哈希,那么有更快的校验和哈希值,如FNV-1a或MurmurHash,它们将提供良好的抗冲突性。

#4


4  

Here is a complete code using C# managed library to compute the hash.

这是一个使用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));
    }
}

#1


30  

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

#2


13  

Here's some code I used to respond to another question on SO

这是我用来回答关于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('=');
}

#3


10  

GetHashCode() is, by default, for internal use only, to check whether two references to an object are in fact the same object. The deafult hash implementation is based on stack/heap location and is thus not going to be deterministic between runs of the program (or even comparing two different references with exactly the same data). So, it should not be used for computing checksums.

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

.NET has an array of built-in libraries that serve this purpose; they're in the System.Security.Cryptography namespace. The two you want are the MD5 and SHA1 classes:

.NET有一系列用于此目的的内置库;它们位于System.Security.Cryptography命名空间中。你想要的两个是MD5和SHA1类:

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

The SHA1 class works the same way.

SHA1类的工作方式相同。

A word of caution; both MD5 and SHA1 are considered "broken" and should not be used in any system requiring a "secure" hash. Consider using the SHA-256 or SHA-512 algorithms in the overall system instead. If you don't need a secure hash, there are faster checksum hashes like FNV-1a or MurmurHash that will provide good collision resistance.

谨慎一点; MD5和SHA1都被视为“已损坏”,不应在任何需要“安全”哈希的系统中使用。请考虑在整个系统中使用SHA-256或SHA-512算法。如果您不需要安全哈希,那么有更快的校验和哈希值,如FNV-1a或MurmurHash,它们将提供良好的抗冲突性。

#4


4  

Here is a complete code using C# managed library to compute the hash.

这是一个使用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));
    }
}