Skip to main content

Class IdCheckCharacter

Namespace: AdCodicem.ValueObjects.Identifiers
Assembly: AdCodicem.ValueObjects.Identifiers.dll

The trailing check character of an entity identifier.

public static class IdCheckCharacter

Inheritance

objectIdCheckCharacter

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 AnyEntityId needs 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

char

The check character.