/// <exception cref="System.InvalidOperationException">HashSize set to an invalid value.</exception> /// <inheritdoc /> protected override byte[] ComputeHashInternal(UnifiedData data) { byte[]? hash = null; switch (HashSize) { case 32: { var h = (uint)InitVal + _primes32[4]; int dataCount = 0; byte[]? remainder = null; var initValues = new[] { (uint)InitVal + _primes32[0] + _primes32[1], (uint)InitVal + _primes32[1], (uint)InitVal, (uint)InitVal - _primes32[0] }; data.ForEachGroup(16, (dataGroup, position, length) => { for (int 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] = initValues[y].RotateLeft(13); initValues[y] *= _primes32[0]; } } dataCount += length; }, (remainderData, position, length) => { remainder = new byte[length]; Array.Copy(remainderData, position, remainder, 0, length); dataCount += length; }); PostProcess(ref h, initValues, dataCount, remainder); hash = BitConverter.GetBytes(h); break; } case 64: { var h = InitVal + _primes64[4]; int dataCount = 0; byte[]? remainder = null; var initValues = new[] { InitVal + _primes64[0] + _primes64[1], InitVal + _primes64[1], InitVal, InitVal - _primes64[0] }; data.ForEachGroup(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] = initValues[y].RotateLeft(31); initValues[y] *= _primes64[0]; } } dataCount += length; }, (remainderData, position, length) => { remainder = new byte[length]; Array.Copy(remainderData, position, remainder, 0, length); dataCount += length; }); PostProcess(ref h, initValues, dataCount, remainder); hash = BitConverter.GetBytes(h); break; } } return(hash ?? Array.Empty <byte>()); }
/// <summary> /// Computes hash value for given stream. /// </summary> /// <param name="data">Data to hash.</param> /// <returns> /// Hash value of data as byte array. /// </returns> protected abstract byte[] ComputeHashInternal(UnifiedData data);