NonCryptographicHashAlgorithm
Represents a non-cryptographic hash algorithm.
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace System.IO.Hashing
{
public abstract class NonCryptographicHashAlgorithm
{
private sealed class CopyToDestinationStream : Stream
{
[CompilerGenerated]
private NonCryptographicHashAlgorithm <hash>P = hash;
public override bool CanWrite => true;
public override bool CanRead => false;
public override bool CanSeek => false;
public override long Length {
get {
throw new NotSupportedException();
}
}
public override long Position {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
public CopyToDestinationStream(NonCryptographicHashAlgorithm hash)
{
}
public override void Write(byte[] buffer, int offset, int count)
{
<hash>P.Append(buffer.AsSpan(offset, count));
}
public override void WriteByte(byte value)
{
<hash>P.Append(new ReadOnlySpan<byte>(new byte[1] {
value
}));
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
<hash>P.Append(buffer.AsSpan(offset, count));
return Task.CompletedTask;
}
public override void Flush()
{
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
}
public int HashLengthInBytes { get; }
protected NonCryptographicHashAlgorithm(int hashLengthInBytes)
{
if (hashLengthInBytes < 1)
throw new ArgumentOutOfRangeException("hashLengthInBytes");
HashLengthInBytes = hashLengthInBytes;
}
public abstract void Append(ReadOnlySpan<byte> source);
public abstract void Reset();
protected abstract void GetCurrentHashCore(Span<byte> destination);
[System.Runtime.CompilerServices.NullableContext(1)]
public void Append(byte[] source)
{
if (source == null)
throw new ArgumentNullException("source");
Append(new ReadOnlySpan<byte>(source));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public void Append(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
stream.CopyTo(new CopyToDestinationStream(this));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public Task AppendAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
if (stream == null)
throw new ArgumentNullException("stream");
return stream.CopyToAsync(new CopyToDestinationStream(this), 81920, cancellationToken);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public byte[] GetCurrentHash()
{
byte[] array = new byte[HashLengthInBytes];
GetCurrentHashCore(array);
return array;
}
public bool TryGetCurrentHash(Span<byte> destination, out int bytesWritten)
{
if (destination.Length < HashLengthInBytes) {
bytesWritten = 0;
return false;
}
GetCurrentHashCore(destination.Slice(0, HashLengthInBytes));
bytesWritten = HashLengthInBytes;
return true;
}
public int GetCurrentHash(Span<byte> destination)
{
if (destination.Length < HashLengthInBytes)
ThrowDestinationTooShort();
GetCurrentHashCore(destination.Slice(0, HashLengthInBytes));
return HashLengthInBytes;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public byte[] GetHashAndReset()
{
byte[] array = new byte[HashLengthInBytes];
GetHashAndResetCore(array);
return array;
}
public bool TryGetHashAndReset(Span<byte> destination, out int bytesWritten)
{
if (destination.Length < HashLengthInBytes) {
bytesWritten = 0;
return false;
}
GetHashAndResetCore(destination.Slice(0, HashLengthInBytes));
bytesWritten = HashLengthInBytes;
return true;
}
public int GetHashAndReset(Span<byte> destination)
{
if (destination.Length < HashLengthInBytes)
ThrowDestinationTooShort();
GetHashAndResetCore(destination.Slice(0, HashLengthInBytes));
return HashLengthInBytes;
}
protected virtual void GetHashAndResetCore(Span<byte> destination)
{
GetCurrentHashCore(destination);
Reset();
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use GetCurrentHash() to retrieve the computed hash code.", true)]
public override int GetHashCode()
{
throw new NotSupportedException(System.SR.NotSupported_GetHashCode);
}
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
private protected static void ThrowDestinationTooShort()
{
throw new ArgumentException(System.SR.Argument_DestinationTooShort, "destination");
}
}
}