Class IdCheckCharacter
Namespace: AdCodicem.ValueObjects.Identifiers
Assembly: AdCodicem.ValueObjects.Identifiers.dll
The trailing check character of an entity identifier.
public static class IdCheckCharacter
Inheritance
Inherited Members
object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()
Remarks
The character is (seed(prefix) + Σᵢ wᵢ · vᵢ) mod 32, where vᵢ is the Crockford value of the
i-th data character of the body and wᵢ = 2·(i mod 16) + 1. Its purpose is to turn a mistyped or
truncated identifier into a rejection at the boundary — offline, without a database round trip — rather than
into a lookup that misses, or worse, one that hits something else.
What it guarantees, stated exactly, because a checksum that promises more than it delivers is worse than none at all:
- every single-character substitution in the body is detected: the weights are odd, hence invertible modulo 32, and a non-zero difference of Crockford values can never be congruent to zero modulo 32;
- every adjacent transposition is detected unless the two characters' values differ by exactly 16 — the weight difference between adjacent positions is congruent to 2 modulo 32 everywhere, the wrap included;
-
the prefix enters through the seed, so the same body under two different prefixes yields a different check
character for 31 prefixes out of 32. A body copied between two identifier types is therefore caught even by
a validator that does not yet know which prefix to expect, which is what
AnyEntityIdneeds before it has resolved anything; - random corruption slips through with probability 1/32. That is the information-theoretic limit of one check character over a 32-symbol alphabet, and no scheme does better.
Methods
Compute(ReadOnlySpan<char>, ReadOnlySpan<char>)
Computes the check character of a body.
public static char Compute(ReadOnlySpan<char> prefix, ReadOnlySpan<char> bodyData)
Parameters
prefix ReadOnlySpan<char>
Declared prefix of the identifier type, without its trailing separator.
bodyData ReadOnlySpan<char>
The data characters of the body — the time bucket and the random part — with the check character excluded. Every character must decode; a character that does not contributes nothing, which is harmless because validation refuses it before the check character is ever consulted.
Returns
The check character.