This week we hashed out some hash algorithms (haha yup, puns intended haha). I was specifically looking at Secure Hash Algorithm (SHA). Well, at work I thought we could use it for one feature I worked on a few months ago. Low and behold my boss suggested using SHA256 instead of SHA512......hhhhhmmmm what's the diff? Runtime performance was the answer, seems completely legit but what exactly is the performance hit with double the hash size? Sounds like a testing prog to me! COOL!
So here's what I came up with.
private static void Calculate( HashAlgorithm algorithm, string notes )
{
Console.WriteLine( "Algorithm = {0}, HashSize = {1}", notes, algorithm.HashSize );
Stopwatch stopwatch = Stopwatch.StartNew();
byte[] hash = algorithm.ComputeHash( file );
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
string hashValue = Convert.ToBase64String( hash );
Console.WriteLine( string.Format( "Hash = '{0}' ({1}), Time: {2:00}:{3:00}",
hashValue, hashValue.Length, ts.Seconds, ts.Milliseconds ) );
}
The main piece here is HashAlgorithm is the base class for MD5, RIPEMD160 (new .NET replacement for MD5) and all the SHA variants.
The next piece of code just calls the Calculate with the desired algorithm. The variants are clumped together to see if there was any runtime differences (there wasn't).
static void Main( string[] args )
{
string filename = "C:/Windows/System32/MRT.exe";
file = File.ReadAllBytes( filename ); //force the prog to read everything into memory now
Console.WriteLine( string.Format( "FileName = {0}, FileSize = {1:000,000}b", filename, file.Length ) );
Console.WriteLine();
Calculate( MD5.Create(), "MD5" );
Calculate( MD5Cng.Create(), "MD5Cng" );
Calculate( MD5CryptoServiceProvider.Create(), "MD5CryptoSrvcPrvdr" );
Console.WriteLine( "MD5Managed doesn't exist" );
Console.WriteLine();
Calculate( RIPEMD160.Create(), "RIPEMD160" );
Console.WriteLine( "RIPEMD160Cng doesn't exist" );
Console.WriteLine( "RIPEMD160CryptoServiceProvider doesn't exist" );
Calculate( RIPEMD160Managed.Create(), "RIPEMD160Managed" );
Console.WriteLine();
Calculate( SHA1.Create(), "SHA1" );
Calculate( SHA1Cng.Create(), "SHA1Cng" );
Calculate( SHA1CryptoServiceProvider.Create(), "SHA1CryptoSrvcPrvdr" );
Calculate( SHA1Managed.Create(), "SHA1Managed" );
Console.WriteLine();
Calculate( SHA256.Create(), "SHA256" );
Calculate( SHA256Cng.Create(), "SHA256Cng" );
Calculate( SHA256CryptoServiceProvider.Create(), "SHA256CryptoSrvcPrvdr" );
Calculate( SHA256Managed.Create(), "SHA1Managed" );
Console.WriteLine();
Calculate( SHA384.Create(), "SHA384" );
Calculate( SHA384Cng.Create(), "SHA384Cng" );
Calculate( SHA384CryptoServiceProvider.Create(), "SHA384CryptoSrvcPrvdr" );
Calculate( SHA384Managed.Create(), "SHA1Managed" );
Console.WriteLine();
Calculate( SHA512.Create(), "SHA512" );
Calculate( SHA512Cng.Create(), "SHA512Cng" );
Calculate( SHA512CryptoServiceProvider.Create(), "SHA512CryptoSrvcPrvdr" );
Calculate( SHA512Managed.Create(), "SHA1Managed" );
Console.ReadLine();
}
The crux of this is to try to illustrate the differences between the different hash algorithms. Here's what the above gives me at runtime (your milage may vary depending on the processor, machine, memory, how many coffees you've had, how many times you been hit with a hockey puck, you know, THAT type of stuff.

You'll find (as to be expected) SHA1 is the quickest (DUH! you might say LOL). BUT I wasn't expecting the SHA512 to be faster than SHA256. To try to ensure I wasn't missing any Timmy's coffees today (thanks SG for my 1st shot of caffeine this AM :>), I tried to look at the runtimes of the other SHA variants (Cng, CryptoServiceProvider and Managed) but those didn't change things one iotta!
If you have any comments, please leave them and I will be happy to read and learn! Now, it's time to grab a coffee and get coding!
PS Here's another runtime screen shot of what this looks like on a Core 2 Quad, just for comparison's sake.

Source Code: http://www.pchenry.com:8080/svn/Blog/trunk/2009/GenerateFileHashes