BlockNonCryptographicHashAlgorithm Class
Definition
- Assembly
- Bodu.IO.Hashing.dll
- Package
- Bodu.IO.Hashing 1.0.0
Base class for non-cryptographic hash algorithms whose internal state advances one fixed-size block at a time -
handles residual buffering, block alignment, total-length tracking, snapshot-based GetCurrentHash, and
optional final-block padding so that derived implementations only need to express the per-block compression step.
public abstract class BlockNonCryptographicHashAlgorithm : NonCryptographicHashAlgorithm
- Inheritance
-
BlockNonCryptographicHashAlgorithm
- Derived
- Inherited Members
- Extension Methods
-
NonCryptographicHashAlgorithmExtensions.ComputeHash(NonCryptographicHashAlgorithm, byte[], int, int)NonCryptographicHashAlgorithmExtensions.TryVerifyHash(NonCryptographicHashAlgorithm, byte[], byte[])NonCryptographicHashAlgorithmExtensions.TryVerifyHash(NonCryptographicHashAlgorithm, byte[], string)NonCryptographicHashAlgorithmExtensions.TryVerifyHash(NonCryptographicHashAlgorithm, Stream, byte[])
Examples
// Sketch of a derived block hash. The base class drives buffering and snapshotting; the
// derived type only expresses how a single block mutates the accumulator.
public sealed class MyBlockHash : BlockNonCryptographicHashAlgorithm
{
private uint _state;
public MyBlockHash()
: base(hashLengthInBytes: 4, blockSize: 16) { }
protected override void ProcessBlock(ReadOnlySpan<byte> block)
{
// mix the 16-byte block into _state ...
}
protected override byte[] PadBlock(ReadOnlySpan<byte> trailing, ulong messageLength)
{
// append a 0x80 byte, zero-pad, then write messageLength little-endian;
// return one or more whole blocks.
return Array.Empty<byte>();
}
protected override byte[] ProcessFinalBlock() =>
BitConverter.GetBytes(_state);
protected override BlockNonCryptographicHashAlgorithm Clone()
{
var copy = new MyBlockHash { _state = _state };
copy.CopyResidualStateFrom(this);
return copy;
}
}
Remarks
Many non-cryptographic hashes - Murmur, CityHash, Pearson, the FNV variants - define their compression step over a fixed block size (4, 8, 16, or 32 bytes) and must buffer trailing bytes that do not fill a complete block. Writing that buffering loop correctly is fiddly: handle straddling input, accumulate the running message length, and pad once on finalization. BlockNonCryptographicHashAlgorithm centralizes that machinery so derived types only express the algorithm-specific behavior.
Inheritance contract. Derived classes implement four members and may override two more:
- ProcessBlock(ReadOnlySpan<byte>) - compress a single complete block.
- PadBlock(ReadOnlySpan<byte>, ulong) - pad the final partial block and encode the total message length.
- ProcessFinalBlock() - emit the final digest from the accumulator.
- Clone() - produce a state-equivalent copy used for non-destructive snapshotting.
- ResetState() (optional) - restore algorithm-specific accumulators on Reset().
- ShouldPadFinalBlock() / AllowUnalignedFinalBlock (optional) - opt out of padding, or pass the padded result as a single block instead of splitting it block-aligned.
Lifecycle. Input arrives via the standard Append(ReadOnlySpan<byte>) entry point and is drained block-by-block into the residual buffer. GetCurrentHash() is intentionally non-destructive: the base class clones the live instance via Clone(), runs padding and finalization on the clone, and copies the digest into the destination span. Callers may inspect the running hash as often as they like without disturbing further input. Reset() clears the residual buffer and total length before invoking ResetState().
Snapshot helpers for derived Clone() implementations. Three protected accessors - ResidualByteCount, ResidualBytes, and TotalLength - expose the base-class state, and CopyResidualStateFrom(BlockNonCryptographicHashAlgorithm) performs the corresponding write-side step. Derived Clone() implementations typically allocate a new instance, copy algorithm-specific accumulators field-by-field, and finish with a call to CopyResidualStateFrom(BlockNonCryptographicHashAlgorithm).
Suitability. Like every other type in Bodu.IO.Hashing, derivations of this class produce
non-cryptographic digests intended for integrity checks, fingerprinting, hash-table keys, and bloom-filter
inputs. They do not provide preimage or collision resistance and must not be used for password hashing, message
authentication, or any security-sensitive context - use a member of Bodu.Security.Cryptography or the BCL's
HashAlgorithm hierarchy instead. Instances are not thread-safe; share
behind explicit synchronization.
Related family. For error detection over a constrained ASCII text domain - card numbers, account identifiers, and serial codes - see the separate check-digit family rooted at CheckDigitAlgorithm. It is intentionally not part of the NonCryptographicHashAlgorithm hierarchy: it consumes char sequences and emits a char/string check value rather than a byte digest.
Constructors
BlockNonCryptographicHashAlgorithm(int, int)
Initializes a new instance of the BlockNonCryptographicHashAlgorithm class using the specified output size and block size.
protected BlockNonCryptographicHashAlgorithm(int hashLengthInBytes, int blockSize)
Parameters
hashLengthInBytesintThe length, in bytes, of the hash produced by this algorithm. Must be greater than zero.
blockSizeintThe block size, in bytes, that the algorithm uses to process input data. Must be greater than zero.
Exceptions
- ArgumentOutOfRangeException
hashLengthInBytes≤ 0, orblockSize≤ 0.
Fields
BlockSizeBytes
The fixed size, in bytes, of each block processed by the algorithm.
protected readonly int BlockSizeBytes
Field Value
Properties
AllowUnalignedFinalBlock
Gets a value indicating whether the final padded block must be sliced into aligned blocks, or whether the full padded result may be passed as a single block.
protected virtual bool AllowUnalignedFinalBlock { get; }
Property Value
ResidualByteCount
Gets the number of residual bytes currently buffered but not yet processed.
protected int ResidualByteCount { get; }
Property Value
Remarks
Exposed to derived types that snapshot state in Clone().
ResidualBytes
Gets a read-only view over the residual byte buffer.
protected ReadOnlySpan<byte> ResidualBytes { get; }
Property Value
Remarks
Exposed to derived types that snapshot state in Clone().
TotalLength
Gets the total number of bytes that have been passed to Append(ReadOnlySpan<byte>) since the last call to Reset().
protected ulong TotalLength { get; }
Property Value
Remarks
Exposed to derived types that snapshot state in Clone().
Methods
Append(ReadOnlySpan<byte>)
When overridden in a derived class, appends the contents of source to the data already processed for the current hash computation.
public override void Append(ReadOnlySpan<byte> source)
Parameters
sourceReadOnlySpan<byte>The data to process.
Clone()
Creates a deep copy of the current algorithm instance, preserving accumulator state. Used by GetCurrentHashCore(Span<byte>) so that retrieving an intermediate hash does not disturb ongoing computation.
protected abstract BlockNonCryptographicHashAlgorithm Clone()
Returns
- BlockNonCryptographicHashAlgorithm
A new instance with the same internal state as the current one.
CopyResidualStateFrom(BlockNonCryptographicHashAlgorithm)
Copies the caller's residual-buffer state onto this instance. Used by Clone() implementations in derived types to duplicate the running input-alignment state.
protected void CopyResidualStateFrom(BlockNonCryptographicHashAlgorithm source)
Parameters
sourceBlockNonCryptographicHashAlgorithmThe algorithm instance whose residual state should be copied.
Exceptions
- ArgumentNullException
sourceis null.
GetCurrentHashCore(Span<byte>)
When overridden in a derived class, writes the computed hash value to destination without modifying accumulated state.
protected override void GetCurrentHashCore(Span<byte> destination)
Parameters
PadBlock(ReadOnlySpan<byte>, ulong)
Pads the final partial block of input data and appends the encoded total message length. This ensures that all input is padded and aligned to the block size required by the algorithm.
protected abstract byte[] PadBlock(ReadOnlySpan<byte> block, ulong messageLength)
Parameters
blockReadOnlySpan<byte>The final block of unprocessed input, typically containing 0 to BlockSizeBytes-1 bytes.
messageLengthulongThe total number of bytes processed by the algorithm before padding, not including this block.
Returns
- byte[]
A padded byte array consisting of one or more full blocks that include the input data and message-length encoding, ready to be passed to ProcessBlock(ReadOnlySpan<byte>).
ProcessBlock(ReadOnlySpan<byte>)
Transforms a complete block of input data and updates the internal hash state.
protected abstract void ProcessBlock(ReadOnlySpan<byte> block)
Parameters
blockReadOnlySpan<byte>The input block to process. Its length must match the algorithm's configured block size.
Exceptions
- ArgumentException
Thrown if the
blockis not the expected size.
ProcessFinalBlock()
Finalizes the hash computation and produces the final hash output.
protected abstract byte[] ProcessFinalBlock()
Returns
- byte[]
A byte array containing the final computed hash value.
Reset()
When overridden in a derived class, resets the hash computation to the initial state.
public override void Reset()
ResetState()
Resets the derived algorithm's internal accumulators. Called from Reset() after base-class state is cleared.
protected virtual void ResetState()
Remarks
Derived types override this to restore any running state they own (for example, partial sums, index counters). The default implementation does nothing.
ShouldPadFinalBlock()
Determines whether the final block of input data should be padded before processing.
protected virtual bool ShouldPadFinalBlock()
Returns
Remarks
By default this method returns true. Derived classes can override to indicate that trailing residual bytes should be processed verbatim without explicit padding.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |