/// <inheritdoc /> protected override void HashCore(byte[] array, int ibStart, int cbSize) { unsafe { fixed(byte *arrayPtr = array) { while (cbSize > 0) { int bytesToCopy = (int)Math.Min(cbSize, BlockSize - _currentOffset); if (bytesToCopy < BlockSize) { Buffer.BlockCopy(array, ibStart, _buffer, (int)_currentOffset, bytesToCopy); _currentOffset += (uint)bytesToCopy; } else { AddBlockHash(MurmurHash3.Create(arrayPtr + ibStart, BlockSize, AlgorithmSeed)); _currentOffset = 0; } ibStart += bytesToCopy; cbSize -= bytesToCopy; } } } }
/// <inheritdoc /> protected override byte[] HashFinal() { // Flush out buffer if (_currentOffset != 0) { unsafe { fixed(byte *arrayPtr = _buffer) { AddBlockHash(MurmurHash3.Create(arrayPtr, _currentOffset, AlgorithmSeed)); } } } // if there are no blocks add an empty block if (_currentBlockOffset == 0) { return(EmptyHashBytes); } else if (_currentBlockOffset > 8) { CombineBlockHashes(); } for (int i = 0; i < 8; i++) { finalHash[i] = _blockHashes[i]; } return(finalHash); }
private void CombineBlockHashes() { unsafe { fixed(byte *arrayPtr = _blockHashes) { MurmurHash3 combinedHash = MurmurHash3.Create(arrayPtr, _currentBlockOffset, AlgorithmSeed); combinedHash.GetHashBytes(_blockHashes, 0); _currentBlockOffset = 8; } } }