n1kita
n1kita

Reputation: 263

How should I compute files hash(md5 & SHA1) in C#

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?

Upvotes: 13

Views: 33584

Answers (4)

Saddam Abu Ghaida
Saddam Abu Ghaida

Reputation: 6729

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

Upvotes: 31

Tony
Tony

Reputation: 1937

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

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

Upvotes: 4

KeithS
KeithS

Reputation: 71565

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.

.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:

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

The SHA1 class works the same way.

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.

Upvotes: 11

Brian
Brian

Reputation: 38025

Here's some code I used to respond to another question on 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('=');
}

Upvotes: 13

Related Questions