Fletcher Class
Definition
Provides a base class for the Fletcher checksum family (Fletcher-16, Fletcher-32, Fletcher-64).
public abstract class Fletcher : BlockNonCryptographicHashAlgorithm, IResumableHashAlgorithm
- Inheritance
-
Fletcher
- Implements
- 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[])
Remarks
Fletcher is a non-cryptographic position-dependent checksum that maintains two running accumulators (A and B) and combines them into the final hash. Derived types Fletcher16, Fletcher32, and Fletcher64 select the output width.
When to choose Fletcher. Fletcher was designed as a cheaper alternative to CRC for detecting accidental corruption in network protocols and file formats - TCP, Modbus ASCII, and ZFS all use a Fletcher variant. It catches single-bit errors and many burst errors at a fraction of CRC's per-byte cost, making it attractive on resource-constrained microcontrollers and in tight inner loops. Pick Fletcher16 for embedded protocols where 16 bits is enough, Fletcher32 as the workhorse for general file-integrity work, and Fletcher64 when a wider checksum reduces collision pressure on large datasets. For stronger error-detection guarantees prefer Crc; for hash-table keying prefer MurmurHash3 or CityHash, which give better avalanche than any positional-sum scheme.
Lifecycle and threading. Inherits the standard
Append(ReadOnlySpan<byte>) /
Reset() /
GetCurrentHash() shape via
BlockNonCryptographicHashAlgorithm. Snapshotting is non-destructive - call GetCurrentHash as
often as needed. Instances are not thread-safe; share behind explicit synchronization, or allocate one per consumer.
important
This algorithm is not cryptographically secure and should not be used for password hashing, digital signatures, or integrity validation in security-sensitive applications.
using Bodu.IO.Hashing.Checksums;
using Bodu.IO.Hashing.Extensions;
// 32-bit Fletcher checksum of a packet payload.
var fletcher = new Fletcher32();
byte[] checksum = fletcher.ComputeHash(payload);
Constructors
Fletcher(int)
Initializes a new instance of the Fletcher class with the specified hash size.
protected Fletcher(int hashSize)
Parameters
hashSizeintThe hash size in bits. Valid values are 16, 32, or 64.
Exceptions
- ArgumentException
Thrown if
hashSizeis not 16, 32, or 64.
Properties
AlgorithmName
Gets the algorithm name in the form Fletcher-N, where N is the output width in bits.
public string AlgorithmName { get; }
Property Value
- string
A string such as
Fletcher-16,Fletcher-32, orFletcher-64.
Methods
Append(ReadOnlySpan<byte>)
Consumes input with deferred modular reduction, amortizing the two modulo operations over a whole Bodu.IO.Hashing.Checksums.Fletcher.ReductionBatch-byte run instead of paying them per byte.
public override void Append(ReadOnlySpan<byte> source)
Parameters
sourceReadOnlySpan<byte>The input bytes to fold into the running accumulators.
Remarks
Both accumulators enter reduced (below Bodu.IO.Hashing.Checksums.Fletcher._modulus), and the batch length is bounded so the running
B accumulator cannot overflow a 64-bit value. Reducing per batch is congruent to - and therefore produces
the identical result as - the per-byte A = (A + b) mod m; B = (B + A) mod m recurrence, regardless of how
the input is split across calls.
This overrides the base per-block driver directly: with a one-byte block size the residual buffer is never populated, so the base ProcessBlock(ReadOnlySpan<byte>) path is used only by the padding branch that ShouldPadFinalBlock() disables for production Fletcher variants.
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 override BlockNonCryptographicHashAlgorithm Clone()
Returns
- BlockNonCryptographicHashAlgorithm
A new instance with the same internal state as the current one.
CreateEmpty()
Creates a new, empty instance of the concrete Fletcher variant. Replaces the former new TSelf() CRTP
construction as the factory the base Clone() uses to snapshot running state.
protected abstract Fletcher CreateEmpty()
Returns
- Fletcher
A fresh instance of the derived variant with default accumulator state.
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 override 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 override 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 override byte[] ProcessFinalBlock()
Returns
- byte[]
A byte array containing the final computed hash value.
ResetState()
Resets the derived algorithm's internal accumulators. Called from Reset() after base-class state is cleared.
protected override 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 override 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.
TryComputeHashFrom(ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>, out int)
Resumes a hash computation from a previously finalized hash value, processes additional input, and writes the new finalized hash to the specified destination span.
public bool TryComputeHashFrom(ReadOnlySpan<byte> previousHash, ReadOnlySpan<byte> newData, Span<byte> destination, out int bytesWritten)
Parameters
previousHashReadOnlySpan<byte>The previously finalized hash value to resume from.
newDataReadOnlySpan<byte>The additional input data to include in the resumed hash calculation.
destinationSpan<byte>The destination buffer to write the finalized hash value to.
bytesWrittenintOutputs the number of bytes written to the destination buffer.
Returns
- bool
true if the resumed and finalized hash was written successfully; otherwise, false if the destination span was too small.
Remarks
Fletcher digests carry the complete accumulator state (the high half is B, the low half A, both
big-endian), so resuming requires no finalization reversal: the halves seed the accumulators directly. The
computation runs against saved-and-restored instance state, so any in-progress incremental state on the instance
survives the call unchanged.
Exceptions
- ArgumentException
Thrown if the
previousHashlength does not match HashLengthInBytes.
Explicit Interface Implementations
IResumableHashAlgorithm.get_HashLengthInBytes()
int IResumableHashAlgorithm.get_HashLengthInBytes()
Returns
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |