/// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { UInt32 a = 0x9e3779b9; UInt32 b = 0x9e3779b9; UInt32 c = _config.Seed; int dataCount = 0; await data.ForEachGroupAsync(12, (dataGroup, position, length) => { ProcessGroup(ref a, ref b, ref c, dataGroup, position, length); dataCount += length; }, (remainder, position, length) => { ProcessRemainder(ref a, ref b, ref c, remainder, position, length); dataCount += length; }, cancellationToken) .ConfigureAwait(false); c += (UInt32)dataCount; Mix(ref a, ref b, ref c); return(BitConverter.GetBytes(c)); }
protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var dataArray = await data.ToArrayAsync(cancellationToken) .ConfigureAwait(false); return(BitConverter.GetBytes( ComputeHashFromArray(dataArray))); }
/// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var prime = _fnvPrimeOffset.Prime; var offset = _fnvPrimeOffset.Offset; // Handle 32-bit and 64-bit cases in a strongly-typed manner for performance if (HashSizeInBits == 32) { var hash = offset[0]; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes32(ref hash, prime[0], dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); return(BitConverter.GetBytes(hash)); } else if (HashSizeInBits == 64) { var hash = ((UInt64)offset[1] << 32) | offset[0]; var prime64 = ((UInt64)prime[1] << 32) | prime[0]; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes64(ref hash, prime64, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); return(BitConverter.GetBytes(hash)); } // Process extended-sized FNV. { var hash = offset.ToArray(); await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref hash, prime, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); return(UInt32ArrayToBytes(hash) .ToArray()); } }
protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var internalState = new InternalState(_config.Seed); await data.ForEachGroupAsync( 32, internalState.ProcessGroup, internalState.ProcessRemainder, cancellationToken) .ConfigureAwait(false); return(internalState.GetResult()); }
protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { UInt32 h = 0; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); return(BitConverter.GetBytes(h)); }
/// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var h = new byte[HashSizeInBits / 8]; bool firstByte = true; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, ref firstByte, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); return(h); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { UInt32 a = 0xdeadbeef + (UInt32)data.Length + _config.Seed; UInt32 b = a; UInt32 c = a; if (_config.HashSizeInBits == 64) { c += _config.Seed2; } int dataCount = 0; await data.ForEachGroupAsync(12, (dataGroup, position, length) => { ProcessGroup(ref a, ref b, ref c, ref dataCount, dataGroup, position, length); }, (remainder, position, length) => { ProcessRemainder(ref a, ref b, ref c, ref dataCount, remainder, position, length); }, cancellationToken) .ConfigureAwait(false); if (dataCount > 0) { Final(ref a, ref b, ref c); } byte[] hash; switch (_config.HashSizeInBits) { case 32: hash = BitConverter.GetBytes(c); break; case 64: hash = BitConverter.GetBytes((((UInt64)b) << 32) | c); break; default: throw new NotImplementedException(); } return(hash); }
/// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var internalState = new InternalState(_config.HashSizeInBits, _originalKeyLength, _salt, _personalization); if (_originalKeyLength > 0) { ProcessBytes(internalState, _key, 0, _key.Length); } await data.ForEachGroupAsync( BlockSizeBytes, (array, start, count) => ProcessBytes(internalState, array, start, count), (array, start, count) => ProcessBytes(internalState, array, start, count), cancellationToken) .ConfigureAwait(false); return(Final(_config.HashSizeInBits, internalState)); }
/// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { UInt32 h = _config.Seed ^ ((UInt32)data.Length * m); await data.ForEachGroupAsync(4, (dataGroup, position, length) => { ProcessGroup(ref h, dataGroup, position, length); }, (remainder, position, length) => { ProcessRemainder(ref h, remainder, position, length); }, cancellationToken) .ConfigureAwait(false); h *= m; h ^= h >> 10; h *= m; h ^= h >> 17; return(BitConverter.GetBytes(h)); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { byte[] hash = null; var dataArray = await data.ToArrayAsync(cancellationToken) .ConfigureAwait(false); switch (_config.HashSizeInBits) { case 32: hash = BitConverter.GetBytes( ComputeHash32(dataArray)); break; case 64: hash = BitConverter.GetBytes( ComputeHash64(dataArray)); break; case 128: var result = ComputeHash128(dataArray); hash = new byte[16]; BitConverter.GetBytes(result.Low) .CopyTo(hash, 0); BitConverter.GetBytes(result.High) .CopyTo(hash, 8); break; default: throw new NotImplementedException(); } return(hash); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { byte[] hash = null; switch (_config.HashSizeInBits) { case 32: { const UInt32 m = unchecked ((UInt32)MixConstant); UInt32 h = (UInt32)_config.Seed ^ (UInt32)data.Length; await data.ForEachGroupAsync(4, (dataGroup, position, length) => { ProcessGroup(ref h, m, dataGroup, position, length); }, (remainder, position, length) => { ProcessRemainder(ref h, m, remainder, position, length); }, cancellationToken) .ConfigureAwait(false); // Do a few final mixes of the hash to ensure the last few // bytes are well-incorporated. h ^= h >> 13; h *= m; h ^= h >> 15; hash = BitConverter.GetBytes(h); break; } case 64: { const UInt64 m = MixConstant; UInt64 h = _config.Seed ^ ((UInt64)data.Length * m); await data.ForEachGroupAsync(8, (dataGroup, position, length) => { ProcessGroup(ref h, m, dataGroup, position, length); }, (remainder, position, length) => { ProcessRemainder(ref h, m, remainder, position, length); }, cancellationToken) .ConfigureAwait(false); h ^= h >> 47; h *= m; h ^= h >> 47; hash = BitConverter.GetBytes(h); break; } default: { throw new NotImplementedException(); } } return(hash); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { byte[] hash; switch (_config.HashSizeInBits) { case 32: { var h = ((UInt32)_config.Seed) + _primes32[4]; ulong dataCount = 0; byte[] remainder = null; var initValues = new[] { ((UInt32)_config.Seed) + _primes32[0] + _primes32[1], ((UInt32)_config.Seed) + _primes32[1], ((UInt32)_config.Seed), ((UInt32)_config.Seed) - _primes32[0] }; await data.ForEachGroupAsync(16, (dataGroup, position, length) => { for (var x = position; x < position + length; x += 16) { for (var y = 0; y < 4; ++y) { initValues[y] += BitConverter.ToUInt32(dataGroup, x + (y * 4)) * _primes32[1]; initValues[y] = RotateLeft(initValues[y], 13); initValues[y] *= _primes32[0]; } } dataCount += (ulong)length; }, (remainderData, position, length) => { remainder = new byte[length]; Array.Copy(remainderData, position, remainder, 0, length); dataCount += (ulong)length; }, cancellationToken) .ConfigureAwait(false); PostProcess(ref h, initValues, dataCount, remainder); hash = BitConverter.GetBytes(h); break; } case 64: { var h = _config.Seed + _primes64[4]; ulong dataCount = 0; byte[] remainder = null; var initValues = new[] { _config.Seed + _primes64[0] + _primes64[1], _config.Seed + _primes64[1], _config.Seed, _config.Seed - _primes64[0] }; await data.ForEachGroupAsync(32, (dataGroup, position, length) => { for (var x = position; x < position + length; x += 32) { for (var y = 0; y < 4; ++y) { initValues[y] += BitConverter.ToUInt64(dataGroup, x + (y * 8)) * _primes64[1]; initValues[y] = RotateLeft(initValues[y], 31); initValues[y] *= _primes64[0]; } } dataCount += (ulong)length; }, (remainderData, position, length) => { remainder = new byte[length]; Array.Copy(remainderData, position, remainder, 0, length); dataCount += (ulong)remainder.Length; }, cancellationToken) .ConfigureAwait(false); PostProcess(ref h, initValues, dataCount, remainder); hash = BitConverter.GetBytes(h); break; } default: throw new NotImplementedException(); } return(hash); }
protected override Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { return(OnComputeHashAsyncInternal(data, cancellationToken)); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { byte[] hash = null; switch (HashSizeInBits) { case 8: { byte h = (byte)_config.Seed; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); hash = new byte[] { h }; break; } case 16: { UInt16 h = (UInt16)_config.Seed; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); hash = BitConverter.GetBytes(h); break; } case 32: { UInt32 h = (UInt32)_config.Seed; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); hash = BitConverter.GetBytes(h); break; } case 64: { UInt64 h = _config.Seed; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes(ref h, dataBytes, position, length); }, cancellationToken) .ConfigureAwait(false); hash = BitConverter.GetBytes(h); break; } default: throw new NotImplementedException(); } return(hash); }
private async Task <byte[]> ComputeShortHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { var h = new UInt64[4] { _seed1, _seed2, 0XDEADBEEFDEADBEEF, 0XDEADBEEFDEADBEEF }; var remainderData = new byte[16]; var remainderLength = 0; await data.ForEachGroupAsync(32, (dataGroup, position, length) => { for (int x = position; x < position + length; x += 32) { h[2] += BitConverter.ToUInt64(dataGroup, x); h[3] += BitConverter.ToUInt64(dataGroup, x + 8); ShortMix(h); h[0] += BitConverter.ToUInt64(dataGroup, x + 16); h[1] += BitConverter.ToUInt64(dataGroup, x + 24); } }, (remainder, position, length) => { if (length >= 16) { h[2] += BitConverter.ToUInt64(remainder, position); h[3] += BitConverter.ToUInt64(remainder, position + 8); ShortMix(h); position += 16; length -= 16; } if (length > 0) { Array.Copy(remainder, position, remainderData, 0, length); remainderLength = length; } }, cancellationToken) .ConfigureAwait(false); h[3] = ((UInt64)data.Length) << 56; if (remainderLength > 0) { h[2] += BitConverter.ToUInt64(remainderData, 0); h[3] += BitConverter.ToUInt64(remainderData, 8); } else { h[2] += 0XDEADBEEFDEADBEEF; h[3] += 0XDEADBEEFDEADBEEF; } ShortEnd(h); byte[] hash; switch (_config.HashSizeInBits) { case 32: hash = BitConverter.GetBytes((UInt32)h[0]); break; case 64: hash = BitConverter.GetBytes(h[0]); break; case 128: hash = new byte[16]; BitConverter.GetBytes(h[0]) .CopyTo(hash, 0); BitConverter.GetBytes(h[1]) .CopyTo(hash, 8); break; default: throw new NotImplementedException(); } return(hash); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { if (data.Length < 192) { return(await ComputeShortHashAsyncInternal(data, cancellationToken) .ConfigureAwait(false)); } UInt64[] h = new UInt64[12]; h[0] = h[3] = h[6] = h[9] = _seed1; h[1] = h[4] = h[7] = h[10] = _seed2; h[2] = h[5] = h[8] = h[11] = 0XDEADBEEFDEADBEEF; var remainderData = new byte[96]; await data.ForEachGroupAsync(96, (dataGroup, position, length) => { Mix(h, dataGroup, position, length); }, (remainder, position, length) => { Array.Copy(remainder, position, remainderData, 0, length); remainderData[95] = (byte)length; }, cancellationToken) .ConfigureAwait(false); Mix(h, remainderData, 0, remainderData.Length); End(h); byte[] hash; switch (_config.HashSizeInBits) { case 32: hash = BitConverter.GetBytes((UInt32)h[0]); break; case 64: hash = BitConverter.GetBytes(h[0]); break; case 128: hash = new byte[16]; BitConverter.GetBytes(h[0]) .CopyTo(hash, 0); BitConverter.GetBytes(h[1]) .CopyTo(hash, 8); break; default: throw new NotImplementedException(); } return(hash); }
/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override async Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken) { byte[] hash; switch (_config.HashSizeInBits) { case 32: { UInt32 h1 = _config.Seed; int dataCount = 0; await data.ForEachGroupAsync(4, (dataGroup, position, length) => { ProcessGroup(ref h1, dataGroup, position, length); dataCount += length; }, (remainder, position, length) => { ProcessRemainder(ref h1, remainder, position, length); dataCount += length; }, cancellationToken) .ConfigureAwait(false); h1 ^= (UInt32)dataCount; Mix(ref h1); hash = BitConverter.GetBytes(h1); break; } case 128: { UInt64 h1 = (UInt64)_config.Seed; UInt64 h2 = (UInt64)_config.Seed; int dataCount = 0; await data.ForEachGroupAsync(16, (dataGroup, position, length) => { ProcessGroup(ref h1, ref h2, dataGroup, position, length); dataCount += length; }, (remainder, position, length) => { ProcessRemainder(ref h1, ref h2, remainder, position, length); dataCount += length; }, cancellationToken) .ConfigureAwait(false); h1 ^= (UInt64)dataCount; h2 ^= (UInt64)dataCount; h1 += h2; h2 += h1; Mix(ref h1); Mix(ref h2); h1 += h2; h2 += h1; hash = new byte[16]; BitConverter.GetBytes(h1) .CopyTo(hash, 0); BitConverter.GetBytes(h2) .CopyTo(hash, 8); break; } default: throw new NotImplementedException(); } return(hash); }
/// <summary> /// Computes hash value for given stream asynchronously. /// </summary> /// <param name="data">Data to hash.</param> /// <param name="cancellationToken">A cancellation token to observe while calculating the hash value.</param> /// <returns> /// Hash value of data as byte array. /// </returns> /// <exception cref="TaskCanceledException">The <paramref name="cancellationToken"/> was canceled.</exception> protected abstract Task <byte[]> ComputeHashAsyncInternal(IUnifiedDataAsync data, CancellationToken cancellationToken);