Crc Class
Definition
General-purpose CRC (Cyclic Redundancy Check) engine driven by a CrcStandard parameter set - supports any catalogue width from 1 to 64 bits, snapshot-style intermediate digests, and resumption of a previous digest with additional input.
public sealed class Crc : NonCryptographicHashAlgorithm, IResumableHashAlgorithm
- Inheritance
-
Crc
- Implements
- 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
CRCs are the workhorse of integrity checks in storage, networking, and file formats: every .zip, .png,
Ethernet frame, USB packet, and Modbus message uses one. Each protocol bakes in slightly different choices -
polynomial, initial value, input/output bit reflection, final XOR - and the same byte sequence can produce a
different digest under CRC-16/ARC, CRC-16/MODBUS, or CRC-32/ISO-HDLC. Rather than ship a class
per variant, Crc consumes the parameters from a CrcStandard and the same engine
computes the right answer for every catalogue entry.
Picking a standard. The full RevEng catalogue is exposed two ways:
- CrcStandard static properties For the common entries (CRC32_ISOHDLC, CRC32_ISCSI, CRC16_MODBUS, …) - direct, allocation-free references to the canonical instance.
- Get(CrcStandards) with a CrcStandards enum value For programmatic look-up across the full catalogue (e.g. when reading a configuration value).
- FromName(string)
Resolves both canonical names and aliases -
"CRC-32","PKZIP","CRC-32/ISO-HDLC"all return the same instance.
API surface. Crc derives from
NonCryptographicHashAlgorithm and exposes the standard
Append(ReadOnlySpan<byte>) /
Reset() /
GetCurrentHash() shape. The
NonCryptographicHashAlgorithmExtensions companion adds one-shot
ComputeHash, stream variants, and constant-time VerifyHash / TryVerifyHash on top.
Snapshot semantics. The final reflection, XOR-out, and width mask are applied to a copy of
the running accumulator, so GetCurrentHash() can be
called as often as the caller likes without disturbing further Append calls - useful for emitting progressive
checksums of an unfinished stream.
Resumption. Crc implements IResumableHashAlgorithm: given a previously emitted digest and additional bytes, it produces the digest of the concatenated input without needing the original bytes back - handy for log-tail integrity checks and content-addressed storage. Resumption is only valid against a digest produced by an instance configured with the same CrcStandard.
Performance. Lookup tables are precomputed once per (width, polynomial, reflectIn) tuple and
shared via GlobalCache, so creating multiple Crc instances for the same standard is
cheap. The hot path uses byte-at-a-time table lookups; for throughput-critical code consider re-using a single
instance and feeding it large spans rather than repeatedly constructing new ones. Instances are not
thread-safe; share behind explicit synchronization.
important
CRC is not cryptographically secure. It detects accidental corruption, not
adversarial tampering - collisions are easy to construct. Use a member of Bodu.Security.Cryptography or
HashAlgorithm for password hashing, digital signatures, message
authentication, or any context where a determined attacker could choose the input.
using System.IO.Hashing;
using Bodu.IO.Hashing;
using Bodu.IO.Hashing.Checksums;
using Bodu.IO.Hashing.Extensions;
// 1. Standard PKZIP / Ethernet CRC-32 of a buffer.
var crc32 = new Crc(CrcStandard.CRC32_ISOHDLC);
byte[] digest = crc32.ComputeHash(File.ReadAllBytes("payload.bin"));
// 2. Modbus RTU - different polynomial/init/reflect choices, same engine.
var modbus = new Crc(CrcStandard.CRC16_MODBUS);
modbus.Append(frameHeader);
modbus.Append(framePayload);
byte[] frameCrc = modbus.GetCurrentHash(); // non-destructive snapshot
// 3. Resumption - fold an appended log segment into yesterday's digest without re-reading
// the original bytes.
var resumable = (IResumableHashAlgorithm)new Crc(CrcStandard.CRC32_ISOHDLC);
byte[] updated = resumable.ComputeHashFrom(digest, File.ReadAllBytes("payload.appended.bin"));
Constructors
Crc()
Initializes a new instance of the Crc class using the default CRC standard (CRC-32/ISO-HDLC).
public Crc()
Remarks
The default standard is CRC-32 (ISO-HDLC) with width 32, polynomial 0x04C11DB7, initial value
0xFFFFFFFF, reflected input and output, and final XOR 0xFFFFFFFF.
Crc(CrcStandard)
Initializes a new instance of the Crc class using the specified CrcStandard.
public Crc(CrcStandard crcStandard)
Parameters
crcStandardCrcStandardThe CRC parameters (polynomial, width, reflection, initial value, final XOR) to use.
Exceptions
- ArgumentNullException
crcStandardis null.- ArgumentOutOfRangeException
The Size of
crcStandardis outside the supported range (1 to 64 bits).
Properties
CrcStandard
Gets the CrcStandard parameters that configure this instance.
public CrcStandard CrcStandard { get; }
Property Value
- CrcStandard
The immutable CrcStandard supplied to the constructor.
GlobalCache
Gets or sets the process-wide cache used to share CRC lookup tables across Crc instances.
public static CrcLookupTableCache GlobalCache { get; set; }
Property Value
- CrcLookupTableCache
The active CrcLookupTableCache. A default cache is lazily created when first accessed.
Exceptions
- ArgumentNullException
The value being assigned is null.
InitialValue
Gets the initial value used in the CRC calculation.
public ulong InitialValue { get; }
Property Value
Name
Gets the name of the CRC standard.
public string Name { get; }
Property Value
Polynomial
Gets the polynomial used in the CRC calculation.
public ulong Polynomial { get; }
Property Value
ReflectIn
Gets a value indicating whether input bytes are reflected (bit-reversed) before being processed.
public bool ReflectIn { get; }
Property Value
ReflectOut
Gets a value indicating whether the CRC result is reflected before XOR-ing with XOrOut.
public bool ReflectOut { get; }
Property Value
Size
Gets the size, in bits, of the CRC checksum.
public int Size { get; }
Property Value
XOrOut
Gets the value to XOR the final CRC result with.
public ulong XOrOut { get; }
Property Value
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.
ComputeHash(ReadOnlySpan<byte>)
Computes and returns the CRC hash of the specified input in a single call, resetting internal state both before and after the computation.
public byte[] ComputeHash(ReadOnlySpan<byte> data)
Parameters
dataReadOnlySpan<byte>The input data to hash.
Returns
Remarks
State is reset after finalization as well as before, matching the reset-before-and-after semantics of the shared
ComputeHash extension (GetHashAndReset). This keeps the instance reusable for a subsequent
Append(ReadOnlySpan<byte>) without the prior input bleeding into the new digest.
ComputeHashFrom(byte[], byte[])
Resumes a hash computation from a previously finalized hash value and processes additional input, returning the new finalized hash result as a byte array.
public byte[] ComputeHashFrom(byte[] previousHash, byte[] newData)
Parameters
previousHashbyte[]The previously finalized hash value to resume from. Must not be null.
newDatabyte[]The additional input data to include in the resumed hash calculation. Must not be null.
Returns
- byte[]
A byte array containing the new finalized hash result.
Remarks
Reverses finalization on previousHash by undoing XOR-out and reflection (if applicable),
continues the CRC computation with the full newData array, and returns the finalized CRC
hash value as a new byte array.
Exceptions
- ArgumentNullException
previousHashornewDatais null.- ArgumentException
Thrown if the
previousHashlength does not match HashLengthInBytes.
ComputeHashFrom(byte[], byte[], int, int)
Resumes a hash computation from a previously finalized hash value and processes a specified range of new data, returning the new finalized hash result as a byte array.
public byte[] ComputeHashFrom(byte[] previousHash, byte[] newData, int offset, int length)
Parameters
previousHashbyte[]The previously finalized hash value to resume from. Must not be null.
newDatabyte[]The buffer containing additional input data. Must not be null.
offsetintThe zero-based offset into
newDataat which to begin reading data.lengthintThe number of bytes to read from
newData.
Returns
- byte[]
A byte array containing the new finalized hash result.
Remarks
Reverses finalization on previousHash and continues the CRC computation with a sliced
segment of newData (starting at offset and spanning
length).
Exceptions
- ArgumentNullException
previousHashornewDatais null.- ArgumentException
Thrown if the
previousHashlength does not match HashLengthInBytes, or if the offset and length exceed the bounds ofnewData.
ComputeHashFrom(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Resumes a hash computation from a previously finalized hash value and processes additional input, returning the new finalized hash result as a byte array.
public byte[] ComputeHashFrom(ReadOnlySpan<byte> previousHash, ReadOnlySpan<byte> newData)
Parameters
previousHashReadOnlySpan<byte>The previously finalized hash value to resume from.
newDataReadOnlySpan<byte>The additional input data to include in the resumed hash calculation.
Returns
- byte[]
A byte array containing the new finalized hash result.
Remarks
Reverses finalization on previousHash, resumes the CRC computation with the contents of
newData, and returns the final CRC hash as a new byte array.
Exceptions
- ArgumentException
Thrown if the
previousHashlength does not match HashLengthInBytes.
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
Remarks
Finalization (output reflection, XOR-out, and width-masking) is applied to a snapshot of the accumulator so that the instance remains usable for further Append(ReadOnlySpan<byte>) calls after retrieval.
Reset()
When overridden in a derived class, resets the hash computation to the initial state.
public override void Reset()
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
Reverses finalization on previousHash by undoing the XOR-out and reflection (if applicable),
continues the CRC computation with newData, and finalizes the result into
destination. The computation is performed against a local copy of the CRC state; any
in-progress incremental state on the instance is preserved and a subsequent
Append(ReadOnlySpan<byte>) continues from where the prior Append(ReadOnlySpan<byte>) calls left off.
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 |