2 // System.Security.Cryptography HashAlgorithm Class implementation
\r
5 // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
\r
6 // Sebastien Pouliot (spouliot@motus.com)
\r
8 // Copyright 2001 by Matthew S. Ford.
\r
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
\r
13 using System.Security.Cryptography;
\r
15 namespace System.Security.Cryptography {
\r
16 public abstract class HashAlgorithm : ICryptoTransform {
\r
17 protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
\r
18 protected int HashSizeValue; // The size of the hash in bits.
\r
19 protected int State; // nonzero when in use; zero when not in use
\r
20 private bool disposed;
\r
23 /// Called from constructor of derived class.
\r
25 protected HashAlgorithm ()
\r
30 // important so we can destory any unmanaged resources
\r
37 /// Get whether or not the hash can transform multiple blocks at a time.
\r
38 /// Note: MUST be overriden if descendant can transform multiple block
\r
39 /// on a single call!
\r
41 public virtual bool CanTransformMultipleBlocks {
\r
42 get { return true; }
\r
45 public virtual bool CanReuseTransform {
\r
46 get { return true; }
\r
49 public void Clear()
\r
51 // same as System.IDisposable.Dispose() which is documented
\r
56 /// Computes the entire hash of all the bytes in the byte array.
\r
58 public byte[] ComputeHash (byte[] input)
\r
60 return ComputeHash (input, 0, input.Length);
\r
63 public byte[] ComputeHash (byte[] buffer, int offset, int count)
\r
66 throw new ObjectDisposedException ("HashAlgorithm");
\r
68 HashCore (buffer, offset, count);
\r
69 HashValue = HashFinal ();
\r
75 public byte[] ComputeHash (Stream inputStream)
\r
77 // don't read stream unless object is ready to use
\r
79 throw new ObjectDisposedException ("HashAlgorithm");
\r
81 int l = (int) (inputStream.Length - inputStream.Position);
\r
82 byte[] buffer = new byte [l];
\r
83 inputStream.Read (buffer, 0, l);
\r
85 return ComputeHash (buffer);
\r
89 /// Creates the default implementation of the default hash algorithm (SHA1).
\r
91 public static HashAlgorithm Create ()
\r
93 return Create ("System.Security.Cryptography.HashAlgorithm");
\r
97 /// Creates a specific implementation of the general hash idea.
\r
99 /// <param name="hashName">Specifies which derived class to create.</param>
\r
100 public static HashAlgorithm Create (string hashName)
\r
102 return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
\r
106 /// Gets the previously computed hash.
\r
108 public virtual byte[] Hash {
\r
110 if (HashValue == null)
\r
111 throw new CryptographicUnexpectedOperationException ();
\r
117 /// When overridden in a derived class, drives the hashing function.
\r
119 /// <param name="rgb"></param>
\r
120 /// <param name="start"></param>
\r
121 /// <param name="size"></param>
\r
122 protected abstract void HashCore (byte[] rgb, int start, int size);
\r
125 /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
\r
127 protected abstract byte[] HashFinal ();
\r
130 /// Returns the size in bits of the hash.
\r
132 public virtual int HashSize {
\r
133 get { return HashSizeValue; }
\r
137 /// When overridden in a derived class, initializes the object to prepare for hashing.
\r
139 public abstract void Initialize ();
\r
141 protected virtual void Dispose (bool disposing)
\r
147 /// Must be overriden if not 1
\r
149 public virtual int InputBlockSize {
\r
154 /// Must be overriden if not 1
\r
156 public virtual int OutputBlockSize {
\r
160 void System.IDisposable.Dispose ()
\r
166 /// Used for stream chaining. Computes hash as data passes through it.
\r
168 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
\r
169 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
\r
170 /// <param name="inputCount">The number of bytes to be copied.</param>
\r
171 /// <param name="outputBuffer">The buffer to write the copied data to.</param>
\r
172 /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
\r
173 public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
\r
175 Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
\r
176 HashCore (inputBuffer, inputOffset, inputCount);
\r
182 /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
\r
184 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
\r
185 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
\r
186 /// <param name="inputCount">The number of bytes to be copied.</param>
\r
187 public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
\r
189 byte[] outputBuffer = new byte[inputCount];
\r
191 Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
\r
193 HashCore (inputBuffer, inputOffset, inputCount);
\r
194 HashValue = HashFinal ();
\r
197 return outputBuffer;
\r