Simple Utility to Calculate File Hashes
I have to download various files from time-to-time, and it's nice when websites provide checksum hashes so I can validate that the file I just downloaded matches the version on the server. (ON a related note, I wrote a blog several years ago which showed how to create a provider for the IIS FTP service which automatically creates checksum files when files are uploaded to a server; see my Automatically Creating Checksum Files for FTP Uploads blog post for the details.)
In order to calculate hashes for files that I have downloaded, several years ago I wrote a simple command-line application for Windows which uses several of the built-in algorithms in .NET's System.Security.Cryptography. And while I realize that there are probably other tools that provide this same functionality, I have used this little utility for years, and I've had several people ask me for copies. With that in mind, I thought that it might make a nice blog topic if I shared the code with everyone. (Note: It's a really simple sample; the .NET framework does all the real work for this application.)
Without further fanfare, here's the source code. In order to use this code sample, you need to create a new C# project in Visual Studio and choose the Console Application template. When the new project opens, replace the template's code with the following:
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Security.Cryptography; class Hash { static void Main(string[] args) { // Verify the correct number of command-line arguments. if (args.Length != 2) { // Show the help message if an incorrect number of arguments was specified. ShowHelp(); return; } else { byte[] hashValue = null; // Verify that the specified file exists. if (!File.Exists(args[1])) { // Show the help message if a non-existent filename was specified. ShowHelp(); return; } else { try { // Create a fileStream for the file. FileStream fileStream = File.OpenRead(args[1]); // Be sure it's positioned to the beginning of the stream. fileStream.Position = 0; // Use the specified hash algorithm. switch (args[0].ToUpper()) { case "MD5": // Compute the MD5 hash of the fileStream. hashValue = MD5.Create().ComputeHash(fileStream); break; case "SHA1": // Compute the SHA1 hash of the fileStream. hashValue = SHA1.Create().ComputeHash(fileStream); break; case "SHA256": // Compute the SHA256 hash of the fileStream. hashValue = SHA256.Create().ComputeHash(fileStream); break; case "SHA384": // Compute the SHA384 hash of the fileStream. hashValue = SHA384.Create().ComputeHash(fileStream); break; case "SHA512": // Compute the SHA512 hash of the fileStream. hashValue = SHA512.Create().ComputeHash(fileStream); break; case "BASE64": // Compute the BASE64 hash of the fileStream. byte[] binaryData = new Byte[fileStream.Length]; long bytesRead = fileStream.Read(binaryData, 0, (int)fileStream.Length); if (bytesRead != fileStream.Length) { throw new Exception(String.Format("Number of bytes read ({0}) does not match file size ({1}).", bytesRead, fileStream.Length)); } string base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length); Console.WriteLine("File: {0}\r\nBASE64 Hash: {1}", fileStream.Name, base64String); hashValue = null; break; default: // Display the help message if an unrecognized hash algorithm was specified. ShowHelp(); return; } if (hashValue != null) { // Write the hash value to the Console. PrintHashData(args[0].ToUpper(), fileStream.Name, hashValue); } // Close the file. fileStream.Close(); } catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); } } } } // Display the help message. private static void ShowHelp() {/> Console.WriteLine("HASH.exe <hash algorithm> <file name>\n\n" + "\tWhere <hash algorithm> is one of the following:\n" + "\t\tBASE64\n\t\tMD5\n\t\tSHA1\n\t\tSHA256\n\t\tSHA384\n\t\tSHA512\n"); } // Print the hash data in a readable format. private static void PrintHashData(string algorithm, string fileName, byte[] array) { Console.Write("File: {0}\r\n{1} Hash: ", fileName,algorithm); for (int i = 0; i < array.Length; i++) { Console.Write(String.Format("{0:X2}", array[i])); } Console.WriteLine(); }/>}
When you compile and run the application, you will see following help message when you specify no command-line parameters:
HASH.exe <hash algorithm> <file name> Where <hash algorithm> is one of the following: BASE64 MD5 SHA1 SHA256 SHA384 SHA512
When you specify one of the supported hashing algorithms and a filename, the application will display something like the following example:
C:\>hash.exe SHA1 foobar.zip File: C:\foobar.zip SHA1 Hash: 57686F6120447564652C20426F6220526F636B73
That's all there is to it. As I mentioned earlier, it's a pretty simple sample. ;-]
(Cross-posted from http://blogs.msdn.com/robert_mcmurray/)