/// <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);
        }
Exemple #2
0
        /// <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();
            }
        }