Table of Contents

BlockNonCryptographicHashAlgorithm Class

Definition

Namespace
Bodu.IO.Hashing
Assembly
Bodu.IO.Hashing.dll
Package
Bodu.IO.Hashing 1.0.0
Source
BlockNonCryptographicHashAlgorithm.cs

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

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:

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

hashLengthInBytes int

The length, in bytes, of the hash produced by this algorithm. Must be greater than zero.

blockSize int

The block size, in bytes, that the algorithm uses to process input data. Must be greater than zero.

Exceptions

ArgumentOutOfRangeException

hashLengthInBytes ≤ 0, or blockSize ≤ 0.

Fields

BlockSizeBytes

The fixed size, in bytes, of each block processed by the algorithm.

protected readonly int BlockSizeBytes

Field Value

int

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

bool

ResidualByteCount

Gets the number of residual bytes currently buffered but not yet processed.

protected int ResidualByteCount { get; }

Property Value

int

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

ReadOnlySpan<byte>

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

ulong

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

source ReadOnlySpan<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

source BlockNonCryptographicHashAlgorithm

The algorithm instance whose residual state should be copied.

Exceptions

ArgumentNullException

source is 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

destination Span<byte>

The buffer that receives the computed hash value.

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

block ReadOnlySpan<byte>

The final block of unprocessed input, typically containing 0 to BlockSizeBytes-1 bytes.

messageLength ulong

The 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

block ReadOnlySpan<byte>

The input block to process. Its length must match the algorithm's configured block size.

Exceptions

ArgumentException

Thrown if the block is 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

bool

true if the final block should be padded; otherwise, false.

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

ProductVersions
.NET8, 10

See Also