InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Displaying progress updates when hashing large files

To hash a file (either using MD5 or SHA1), you can use the corresponding classes in the .NET Framework (MD5 or SHA1) with only a few lines of code:

    1 using (Stream stream = File.OpenRead(filename)

    2 using (MD5 md5 = MD5.Create())

    3 {

    4     md5.ComputeHash(stream);

    5    // Hash can be accessed through md5.HashValue

    6 }

This will compute the hash for the specified filename. But if your file is very large, it would be nice to have a progress bar. But ComputeHash does not implement some sort of callback mechanisms to report progress.

But the HashAlgorithm class (which all hash algorithms in the .NET Framework derive from) has two other methods: TranformBlock and TransformFinalBlock. These methods make it possible to compute the hash from discrete blocks of data. For every block other than the last, call TransformBlock. For the last block, call TransformFinalBlock. The resulting hash is now accessible via the HashValue property.

Here is a sample implementation using a background worker:

    1 privatevoid BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)

    2 {

    3     byte[] buffer;

    4     byte[] oldBuffer;

    5     int bytesRead;

    6     int oldBytesRead;

    7     long size;

    8     long totalBytesRead = 0;

    9 

   10     using (Stream stream = File.OpenRead((string) e.Argument))

   11     using (HashAlgorithm hashAlgorithm = MD5.Create())

   12     {

   13         size = stream.Length;

   14 

   15         buffer = newbyte[4096];

   16 

   17         bytesRead = stream.Read(buffer, 0, buffer.Length);

   18         totalBytesRead += bytesRead;

   19 

   20         do

   21         {

   22             oldBytesRead = bytesRead;

   23             oldBuffer = buffer;

   24 

   25             buffer = newbyte[4096];

   26             bytesRead = stream.Read(buffer, 0, buffer.Length);

   27 

   28             totalBytesRead += bytesRead;

   29 

   30             if (bytesRead == 0)

   31             {

   32                 hashAlgorithm.TransformFinalBlock(oldBuffer, 0, oldBytesRead);

   33             }

   34             else

   35             {

   36                 hashAlgorithm.TransformBlock(oldBuffer, 0, oldBytesRead, oldBuffer, 0);

   37             }

   38 

   39             BackgroundWorker.ReportProgress((int)​((double)totalBytesRead * 100 / size));

   40         } while (bytesRead != 0);

   41 

   42         e.Result = hashAlgorithm.Hash;

   43     }

   44 }

The full source code is attached to this article.

Downloads

Md5Creator.zip (11,121 Bytes)
MD5 Sample application source code

Technorati:

Posted by Henning Krause on Saturday, June 9, 2007 12:00 AM, last modified on Saturday, June 9, 2007 12:00 PM
Permalink | Post RSSRSS comment feed