Skip to content

Instantly share code, notes, and snippets.

@GordonBeeming
Last active March 28, 2024 14:49
Show Gist options
  • Save GordonBeeming/281e019d0b61bf045bd5 to your computer and use it in GitHub Desktop.
Save GordonBeeming/281e019d0b61bf045bd5 to your computer and use it in GitHub Desktop.
Hash Helper class with methods for creating hashes for MD5, SHA1, SHA256, SHA384, SHA512 and RIPEMD160.
using System;
using System.IO;
using System.Security.Cryptography;
/// <summary>
/// https://gist.github.com/Gordon-Beeming/281e019d0b61bf045bd5
/// </summary>
public static class HashHelper
{
public enum Algorithms
{
MD5 = 1,
SHA1 = 2,
SHA256 = 3,
SHA384 = 4,
SHA512 = 5,
}
public static string GetHashFromFile(string fileName, Algorithms algorithm, int bufferSizeInMb = 100)
{
return GetHashFromStream(File.OpenRead(fileName), algorithm, bufferSizeInMb);
}
public static string GetHashOfString(string value, Algorithms algorithm, int bufferSizeInMb = 100)
{
return GetHashFromBytes(GetBytes(value), algorithm, bufferSizeInMb);
}
public async Task<string> GetHashFromStream(Stream ms, Algorithms algorithm, int bufferSizeInMb = 100)
{
using (var stream = new MemoryStream())
{
await ms.CopyToAsync(stream);
stream.Position = 0; // Reset the position
return BitConverter.ToString(GetHashAlgorithm(algorithm).ComputeHash(stream)).Replace("-", string.Empty);
}
}
public static string GetHashFromBytes(byte[] bytes, Algorithms algorithm, int bufferSizeInMb = 100)
{
using (var ms = new MemoryStream(bytes))
{
return GetHashFromStream(ms, algorithm, bufferSizeInMb);
}
}
public static string GetHashFromStream(Stream ms, Algorithms algorithm, int bufferSizeInMb = 100)
{
using (var stream = new BufferedStream(ms, 1024 * 1024 * bufferSizeInMb))
{
return BitConverter.ToString(GetHashAlgorithm(algorithm).ComputeHash(stream)).Replace("-", string.Empty);
}
}
private static HashAlgorithm GetHashAlgorithm(Algorithms algorithm)
{
switch (algorithm)
{
case Algorithms.MD5:
return new MD5CryptoServiceProvider();
case Algorithms.SHA1:
return new SHA1Managed();
case Algorithms.SHA256:
return new SHA256Managed();
case Algorithms.SHA384:
return new SHA384Managed();
case Algorithms.SHA512:
return new SHA512Managed();
}
throw new NotImplementedException();
}
private static byte[] GetBytes(string value)
{
byte[] bytes = new byte[value.Length * sizeof(char)];
System.Buffer.BlockCopy(value.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
}
@GordonBeeming
Copy link
Author

Updated to use an enum for Algorithms because the way it was implemented gave issues for multiple threads smashing the function at the same time and was handing out wrong hashes (well hashes of other calls)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment