Sunday, April 13, 2014

Implementing HashAlgorithm

See the 2022 article titled CRC vs Hash Algorithms for a news update about the CRC and XXHash classes that are now part of the .NET Core class libraries. There is no longer any need to use borrowed code for CRC or SHA3.

I often use the classes MD5 and SHA1 for creating data "fingerprints" or secure hashes. I was pleased to discover recently that authors of the SHA-3 hash algorithm have created a C# implementation and published it as a Nuget package. This means .NET developers can easily use this new NIST certified algorithm.

For years I wondered how hard it was to implement your own hash algorithm and make it look and behave like the standard ones. I vaguely guessed it was tricky due to the large numbers of virtual and abstract base class members. However, after running an experiment one morning I found it's actually quite easy. For my experiment I tried to create a HashAlgorithm implementation that produced a 32-bit output using the CRC-32 algorithm. The resulting class is just this:

public class HashCrc32 : HashAlgorithm
{
  private Crc32 crc;

  public HashCrc32()
  {
     crc = new Crc32();
  }

  protected override void HashCore(byte[] array, int ibStart, int cbSize)
  {
    crc.Update(array, ibStart, cbSize);
  }

  protected override byte[] HashFinal()
  {
    byte[] buff = BitConverter.GetBytes((uint)crc.Value);
    Array.Reverse(buff);
    return buff;
  }

  public override void Initialize()
  {
    crc.Reset();
  }

  public override int HashSize
  {
     get { return 32; }
  }
}

The code for the Crc32 class I use above can be found all over the Internet in various slightly different forms which all seem to work correctly. My own copy can be found in the Orthogonal.Common repository, look under the Basic folder.

As you can see, only a handful of members need to be overridden. The virtual HashCore and HashFinal methods are called by all of the familiar public methods that hash buffers and streams in various ways, so by implementing those virtual methods the class will work correctly in all scenarios.

No comments:

Post a Comment