HashAlgorithm
Represents the base class from which all implementations of cryptographic
hash algorithms must derive.
using System.IO;
namespace System.Security.Cryptography
{
public abstract class HashAlgorithm : IDisposable
{
private byte[] _hashValue;
private bool _disposed;
public virtual int HashSize => 0;
public virtual int InputBlockSize => 0;
public virtual int OutputBlockSize => 0;
public virtual bool CanReuseTransform => true;
public virtual bool CanTransformMultipleBlocks => true;
public byte[] Hash {
get {
if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
return (byte[])_hashValue.Clone();
}
}
public byte[] ComputeHash(byte[] buffer)
{
if (_disposed)
throw new ObjectDisposedException(null);
if (buffer == null)
throw new ArgumentNullException("buffer");
HashCore(buffer, 0, buffer.Length);
return CaptureHashCodeAndReinitialize();
}
public byte[] ComputeHash(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", "Non-negative number required.");
if (count < 0 || count > buffer.Length)
throw new ArgumentException("Value was invalid.");
if (buffer.Length - count < offset)
throw new ArgumentException("Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.");
if (_disposed)
throw new ObjectDisposedException(null);
HashCore(buffer, offset, count);
return CaptureHashCodeAndReinitialize();
}
public byte[] ComputeHash(Stream inputStream)
{
if (_disposed)
throw new ObjectDisposedException(null);
byte[] array = new byte[4096];
int cbSize;
while ((cbSize = inputStream.Read(array, 0, array.Length)) > 0) {
HashCore(array, 0, cbSize);
}
return CaptureHashCodeAndReinitialize();
}
private byte[] CaptureHashCodeAndReinitialize()
{
byte[] array = HashFinal();
array = (_hashValue = (byte[])array.Clone());
Initialize();
return array;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
_disposed = true;
}
protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
protected abstract byte[] HashFinal();
public abstract void Initialize();
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset");
if (inputCount < 0 || inputCount > inputBuffer.Length)
throw new ArgumentException("XX");
if (inputBuffer.Length - inputCount < inputOffset)
throw new ArgumentException("xx");
HashCore(inputBuffer, inputOffset, inputCount);
Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
return inputCount;
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
{
if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset");
if (inputCount < 0 || inputCount > inputBuffer.Length)
throw new ArgumentException("XX");
if (inputBuffer.Length - inputCount < inputOffset)
throw new ArgumentException("xx");
HashCore(inputBuffer, inputOffset, inputCount);
_hashValue = HashFinal();
byte[] array = new byte[inputCount];
Buffer.BlockCopy(inputBuffer, inputOffset, array, 0, inputCount);
return array;
}
}
}