/// <inheritdoc /> protected override async Task<byte[]> ComputeHashAsyncInternal(UnifiedData data) { UInt32 hash = 0; await data.ForEachReadAsync((dataBytes, position, length) => { ProcessBytes(ref hash, dataBytes, position, length); }).ConfigureAwait(false); return BitConverter.GetBytes(hash); }
/// <inheritdoc /> protected override async Task<byte[]> ComputeHashAsyncInternal(UnifiedData data) { // Use 64-bit variable regardless of CRC bit length UInt64 hash = Settings.InitialValue; // Reflect InitialValue if processing as big endian if (Settings.ReflectIn) hash = hash.ReflectBits(HashSize); // Store table reference in local variable to lower overhead. var crcTable = Settings.DataDivisionTable; // How much hash must be right-shifted to get the most significant byte (HashSize >= 8) or bit (HashSize < 8) int mostSignificantShift = HashSize - 8; if (HashSize < 8) mostSignificantShift = HashSize - 1; await data.ForEachReadAsync((dataBytes, position, length) => { ProcessBytes(ref hash, crcTable, mostSignificantShift, dataBytes, position, length); }).ConfigureAwait(false); // Account for mixed-endianness if (Settings.ReflectIn ^ Settings.ReflectOut) hash = hash.ReflectBits(HashSize); hash ^= Settings.XOrOut; return hash.ToBytes(HashSize); }
/// <inheritdoc /> protected override async Task<byte[]> ComputeHashAsyncInternal(UnifiedData data) { var prime = HashParameters[HashSize].Prime; var offset = HashParameters[HashSize].Offset; // Handle 32-bit and 64-bit cases in a strongly-typed manner for performance if (HashSize == 32) { var hash = offset[0]; await data.ForEachReadAsync( (dataBytes, position, length) => { ProcessBytes32(ref hash, prime[0], dataBytes, position, length); }).ConfigureAwait(false); return BitConverter.GetBytes(hash); } else if (HashSize == 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); }).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); }).ConfigureAwait(false); return hash.ToBytes() .ToArray(); } }