Skip to main content
Version: Preview (0.3.0-preview.205)

Class EntityIdFormat

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

The layout of an entity identifier: prefix _ bucket random check.

public static class EntityIdFormat

Inheritance​

object ← EntityIdFormat

Inherited Members​

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()

Remarks​

Generated identifier types call into this rather than carrying their own copy of the layout, so a change to the format is a change in one place. Every member is public because generated code lives in the consumer's assembly and cannot reach anything internal here.

Validation is a span scan, not a regular expression. At fixed length over a fixed alphabet a scan is both faster and simpler than any regular expression, a source-generated one included, and it spares an entity identifier the Regex the deprecated Pattern option compiles at start-up.

Fields​

ChecksumLength​

The number of trailing check characters.

public const int ChecksumLength = 1

Field Value​

int

MaxTotalLength​

The greatest total length any profile can produce, which bounds a stack buffer.

public const int MaxTotalLength = 40

Field Value​

int

RandomLength​

The number of characters carrying randomness, at every granularity.

public const int RandomLength = 16

Field Value​

int

Remarks​

16 symbols of five bits each: 80 bits. The birthday bound is roughly 1.1 × 10¹² identifiers within one time bucket, against the 10⁴–10⁵ a bucket is sized to hold, so a collision is not a thing that happens.

Sized against the bucket, not against the table. Randomness is redrawn on every bucket, so what has to stay out of reach is the number of identifiers minted within one bucket width — orders of magnitude below the row count of the table, and the reason this is 80 bits rather than the 128 an unbucketed identifier would need.

Properties​

EntropyByteCount​

Gets the number of entropy bytes consumes.

public static int EntropyByteCount { get; }

Property Value​

int

Remarks​

One byte per random character. Taking the low five bits of a uniform byte is itself uniform, which reducing a smaller buffer modulo 32 would not be.

Epoch​

Gets the instant the time bucket counts from.

public static DateTimeOffset Epoch { get; }

Property Value​

DateTimeOffset

Remarks​

2020, not 1970. Half a century of elapsed time spent before the first identifier is issued is half the bucket space burned for nothing, and moving the epoch forward buys that back as horizon.

Methods​

BodyLength(IdGranularity)​

Gets the number of characters after the prefix separator.

public static int BodyLength(IdGranularity granularity)

Parameters​

granularity IdGranularity

Bucket width.

Returns​

int

The body length.

Exceptions​

ArgumentOutOfRangeException

granularity is not a declared value.

CarriesPrefix(ReadOnlySpan<char>, string)​

Determines whether a text opens with a prefix and its separator, ignoring case.

public static bool CarriesPrefix(ReadOnlySpan<char> text, string prefix)

Parameters​

text ReadOnlySpan<char>

Text to test.

prefix string

Declared prefix, without its trailing separator.

Returns​

bool

true when the prefix and its separator are present.

Create(string, IdGranularity, TimeProvider, IdEntropySource)​

Builds a new identifier.

public static string Create(string prefix, IdGranularity granularity, TimeProvider timeProvider, IdEntropySource entropy)

Parameters​

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

timeProvider TimeProvider

Clock supplying the bucket.

entropy IdEntropySource

Source of the random part.

Returns​

string

The identifier, canonical and valid by construction.

Exceptions​

ArgumentNullException

An argument is null.

ArgumentException

prefix breaks the prefix rules.

ArgumentOutOfRangeException

granularity is not a declared value.

Example(string, IdGranularity)​

Builds a representative identifier, for publication in an OpenAPI schema.

public static string Example(string prefix, IdGranularity granularity)

Parameters​

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

Returns​

string

A valid identifier of the right shape.

Remarks​

Derived from a fixed instant and a fixed byte pattern rather than minted, so that regenerating the document twice produces the same bytes. An example drawn from the real entropy source would be valid and would make a committed specification churn on every build.

Exceptions​

ArgumentNullException

prefix is null.

ArgumentException

prefix breaks the prefix rules.

ArgumentOutOfRangeException

granularity is not a declared value.

Normalize(ReadOnlySpan<char>, string)​

Rewrites a candidate into its canonical spelling.

public static string Normalize(ReadOnlySpan<char> text, string prefix)

Parameters​

text ReadOnlySpan<char>

Candidate text.

prefix string

Declared prefix, without its trailing separator.

Returns​

string

The canonical identifier, or the trimmed input when it does not carry the declared prefix. Normalization never rejects: a text this could not make sense of is handed to to refuse.

Remarks​

Trims surrounding whitespace, folds the body to its canonical symbols — lower case, with Crockford's aliases mapped — and restores the declared casing of the prefix. Idempotent, as the contract of a normalizer requires.

Length is preserved: nothing is dropped. Crockford allows a hyphen anywhere in an encoded value for readability, and this format deliberately does not, because these identifiers are never transcribed by hand. Repairing a hyphenated candidate would buy a spelling nobody produces at the price of a second text that maps onto the same identifier.

Exceptions​

ArgumentNullException

prefix is null.

SchemaPattern(string, IdGranularity)​

Builds the regular expression describing a profile, for publication in an OpenAPI schema.

public static string SchemaPattern(string prefix, IdGranularity granularity)

Parameters​

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

Returns​

string

An anchored pattern.

Remarks​

Published as schema text and never compiled: the running validation is , a span scan. The pattern exists so that a client generated from the document rejects the same texts.

Exceptions​

ArgumentNullException

prefix is null.

ArgumentOutOfRangeException

granularity is not a declared value.

TimestampLength(IdGranularity)​

Gets the number of characters the time bucket occupies at a granularity.

public static int TimestampLength(IdGranularity granularity)

Parameters​

granularity IdGranularity

Bucket width.

Returns​

int

The number of characters.

Exceptions​

ArgumentOutOfRangeException

granularity is not a declared value.

TotalLength(string, IdGranularity)​

Gets the exact length of an identifier, which is also the width of its database column.

public static int TotalLength(string prefix, IdGranularity granularity)

Parameters​

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

Returns​

int

The total length.

Exceptions​

ArgumentNullException

prefix is null.

ArgumentOutOfRangeException

granularity is not a declared value.

Validate(ReadOnlySpan<char>, string, IdGranularity)​

Validates an already normalized candidate.

public static ValidationResult Validate(ReadOnlySpan<char> value, string prefix, IdGranularity granularity)

Parameters​

value ReadOnlySpan<char>

Normalized candidate.

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

Returns​

ValidationResult

The first rule the candidate breaks, or success.

Exceptions​

ArgumentNullException

prefix is null.

ArgumentOutOfRangeException

granularity is not a declared value.

Write(string, IdGranularity, DateTimeOffset, ReadOnlySpan<byte>, Span<char>)​

Writes an identifier into a destination buffer.

public static int Write(string prefix, IdGranularity granularity, DateTimeOffset timestamp, ReadOnlySpan<byte> entropy, Span<char> destination)

Parameters​

prefix string

Declared prefix, without its trailing separator.

granularity IdGranularity

Bucket width.

timestamp DateTimeOffset

Instant the bucket encodes.

entropy ReadOnlySpan<byte>

At least bytes of randomness.

destination Span<char>

Buffer receiving the identifier.

Returns​

int

The number of characters written.

Exceptions​

ArgumentNullException

prefix is null.

ArgumentException

entropy or destination is too short.

ArgumentOutOfRangeException

granularity is not a declared value.