public static async Task <ReadOnlyMemory <byte> > ComputeHashAsync( this IAsyncEnumerable <byte> enumerable, IHashAlgorithm hashAlgorithm, CancellationToken cancellationToken ) { // Validate parameters. if (enumerable == null) { throw new ArgumentNullException(nameof(enumerable)); } if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } // Memory var buffer = new Memory <byte>(new byte[1]); // Cycle through the items. await foreach (byte b in enumerable.WithCancellation(cancellationToken).ConfigureAwait(false)) { // Copy the byte. var copy = b; // Write the byte to the span MemoryMarshal.Write(buffer.Span, ref copy); // Transform. hashAlgorithm.TransformBlock(buffer.Span); } // Return the hash. return(hashAlgorithm.Hash); }
public static ref readonly ReadOnlyMemory <byte> ComputeHash( this Stream stream, IHashAlgorithm hashAlgorithm, ArrayPool <byte> arrayPool, int bufferSize ) { // Validate parameters. if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (arrayPool == null) { throw new ArgumentNullException(nameof(arrayPool)); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, $"The { nameof(bufferSize) } parameter must be a positive value."); } // The buffer. byte[]? buffer = null; // Wrap in a try/finally. try { // Rent. buffer = arrayPool.Rent(bufferSize); // Cycle through the stream. while (stream.Read(buffer, 0, bufferSize) != 0) { // Run through the hash. hashAlgorithm.TransformBlock(buffer); } // Return. return(ref hashAlgorithm.Hash); } finally { // Release. arrayPool.Return(buffer); } }
public static ref readonly ReadOnlyMemory <byte> ComputeHash(this IHashAlgorithm hashAlgorithm, ReadOnlySpan <byte> bytes) { // Validate parameters. if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } // Transform the block. hashAlgorithm.TransformBlock(bytes); // Return the hash. return(ref hashAlgorithm.Hash); }
public static int GetHashCode(this IHashAlgorithm hashAlgorithm, IEnumerable <int> hashCodes) { // Validate parameters. if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } if (hashCodes == null) { throw new ArgumentNullException(nameof(hashCodes)); } // Unsafe. unsafe { // Cycle through // the hashcodes, transforming each block that's returned. foreach (int hashCode in hashCodes) { // Copy. var hashCodeCopy = hashCode; // Get the pointer. int *p = &hashCodeCopy; // Get the bytes. var bytes = new ReadOnlySpan <byte>(p, sizeof(int)); // Transform the block. hashAlgorithm.TransformBlock(bytes); } } // Return the hash. return(MemoryMarshal.Read <int>(hashAlgorithm.Hash.Span)); }
public virtual int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return(_hashAlgorithm.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset)); }
public static async Task <ReadOnlyMemory <byte> > ComputeHashAsync( this Stream stream, IHashAlgorithm hashAlgorithm, ArrayPool <byte> arrayPool, int bufferSize, CancellationToken cancellationToken ) { // Validate parameters. if (hashAlgorithm == null) { throw new ArgumentNullException(nameof(hashAlgorithm)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (arrayPool == null) { throw new ArgumentNullException(nameof(arrayPool)); } if (bufferSize <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, $"The { nameof(bufferSize) } parameter must be a positive value."); } // The declarations for the buffer and the copy. byte[]? buffer = null; byte[]? copy = null; // Wrap in a try/finally. try { // Allocate. buffer = arrayPool.Rent(bufferSize); copy = arrayPool.Rent(bufferSize); // The bytes read task. Task <int> bytesRead = stream.ReadAsync(buffer, 0, bufferSize, cancellationToken); // No bytes read, get out. if ((await bytesRead.ConfigureAwait(false)) == 0) { return(hashAlgorithm.Hash); } // While there are items to process. do { // Copy the buffer. // NOTE: Need to do this because it's a shared resource. // If tests show there's a sweet spot between the copy time and hash time < next ReadAsync time, // move buffer size accordingly. Array.Copy(buffer, copy, bufferSize); // Read the next task. bytesRead = stream.ReadAsync(buffer, 0, bufferSize, cancellationToken); // Hash. hashAlgorithm.TransformBlock(copy); // Get the next stream immediately. } while (await bytesRead.ConfigureAwait(false) > 0); // Return. return(hashAlgorithm.Hash); } finally { // Release. arrayPool.Return(buffer); arrayPool.Return(copy); } }