views:

101

answers:

2

What is the best solution in C# for computing an "on the fly" md5 like hash of a stream of unknown length? Specifically, I want to compute a hash from data received over the network. I know I am done receiving data when the sender terminates the connection, so I don't know the length in advance.

[EDIT] - Right now I am using md5, but this requires a second pass over the data after it's been saved and written to disk. I'd rather hash it in place as it comes in from the network.

+2  A: 

The System.Security.Cryptography.MD5 class contains a ComputeHash method that takes either a byte[] or Stream. Check it out at http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5_members.aspx

Peter Mourfield
+10  A: 

MD5, like other hash functions, does not require two passes.

To start:

HashAlgorithm hasher = ..;
hasher.Initialize();

As each block of data arrives:

byte[] buffer = ..;
int bytesReceived = ..;
hasher.TransformBlock(buffer, 0, bytesReceived, null);

To finish and retrieve the hash:

hasher.TransformFinalBlock(new byte[0], 0, 0);
byte[] hash = hasher.Hash;

This pattern works for any type derived from HashAlgorithm, including MD5CryptoServiceProvider and SHA1Managed.

HashAlgorithm also defines a method ComputeHash which takes a Stream object; however, this method will block the thread until the stream is consumed. Using the TransformBlock approach allows an "asynchronous hash" that is computed as data arrives without using up a thread.

Stephen Cleary
I had seen those methods but never investigated what they did. Shame on me. This looks like it will work.
John JJ Curtis