// // System.Security.Cryptography HashAlgorithm Class implementation // // Authors: // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu) // // Copyright 2001 by Matthew S. Ford. // using System.Security.Cryptography; namespace System.Security.Cryptography { public abstract class HashAlgorithm : ICryptoTransform { protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property. protected int HashSizeValue; // The size of the hash in bits. protected int State; // nonzero when in use; zero when not in use /// /// Called from constructor of derived class. /// protected HashAlgorithm () { } /// /// FIXME: Always true for hashes? /// Get whether or not the hash can transform multiple blocks at a time. /// public virtual bool CanTransformMultipleBlocks { get { return true; } } /// /// Computes the entire hash of all the bytes in the byte array. /// public virtual byte[] ComputeHash (byte[] input) { // inputData = input.Clone(); HashCore (input, 0, input.Length); HashValue = HashFinal (); Initialize (); return HashValue; } /// /// Creates the default implementation of the default hash algorithm (SHA1). /// public static HashAlgorithm Create () { return SHA1.Create (); } /// /// Creates a specific implementation of the general hash idea. /// /// FIXME: No clue. Specifies which derived class to create. public static HashAlgorithm Create (string st) { return Create (); } /// /// Gets the previously computed hash. /// public virtual byte[] Hash { get { return HashValue; } } /// /// When overridden in a derived class, drives the hashing function. /// /// /// /// protected abstract void HashCore (byte[] rgb, int start, int size); /// /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. /// protected abstract byte[] HashFinal (); /// /// Returns the size in bits of the hash. /// public virtual int HashSize { get { return HashSizeValue; } } /// /// When overridden in a derived class, initializes the object to prepare for hashing. /// public abstract void Initialize (); /// /// FIXME: Not quire valid for the hashes? Returns 1? /// public virtual int InputBlockSize { get { return 1; } } /// /// FIXME: Not quire valid for the hashes? Returns 1? /// public virtual int OutputBlockSize { get { return 1; } } /// /// Used for stream chaining. Computes hash as data passes through it. /// /// The buffer from which to grab the data to be copied. /// The offset into the input buffer to start reading at. /// The number of bytes to be copied. /// The buffer to write the copied data to. /// At what point in the outputBuffer to write the data at. public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount); HashCore (inputBuffer, inputOffset, inputCount); return inputCount; } /// /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. /// /// The buffer from which to grab the data to be copied. /// The offset into the input buffer to start reading at. /// The number of bytes to be copied. public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) { byte[] outputBuffer = new byte[inputCount]; Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount); HashCore (inputBuffer, inputOffset, inputCount); HashValue = HashFinal (); Initialize (); return outputBuffer; } } }