std/identifier/ulid

std/identifier/src/ulid.trb

Ulid: a ULID, 128 bits of a millisecond and an 80-bit random part, shown as twenty-six characters of Crockford base 32 (docs/design/URI.md section 12).

type Ulid

type Ulid with Identifier

A ULID: sixteen bytes, the first six of them the milliseconds since 1970 and the last ten random, shown as twenty-six upper-case characters of Crockford base 32. The text of a later millisecond sorts after the text of an earlier one, and so does compare.

Randomness and the clock are arguments, never read: see Ulid.generated. Uuid is the default for new identifiers (a database column of the type, a urn:uuid:); Ulid is here for a system that is built on ULIDs.

Examples

const parsed = Ulid.tryFrom("01ARZ3NDEKTSV4RRFFQ69G5FAV").expect("a ULID")
print parsed.at().unixNanoseconds()
// prints 1469922850259000000

Related

  • Uuid - the same sixteen bytes in RFC 9562's text.

fn at

fn at(): Timestamp

The millisecond the identifier carries, as a Timestamp of whole milliseconds.

fn generated

static fn generated(var source: Random, at: Timestamp, after: Self? = None): Self

A ULID for at, in whole milliseconds. Where after is a ULID of the same millisecond, its random part incremented by one is the random part and nothing is drawn, which is what the specification calls monotonicity; otherwise two uint64() draws follow, 80 of their 128 bits are the random part (the top 16 bits of the first, then all 64 of the second). The layout is frozen like Random's, so a seeded source makes the same ULID on every toolchain.

Examples

var source = Random.seeded 42
const now = Timestamp.fromUnixNanoseconds 1_790_000_000_000_000_000
const first = Ulid.generated source, at: now
const second = Ulid.generated source, at: now, after: first
print(second > first)
// prints true

Panics

Where at is before 1970-01-01, and where after is of the same millisecond with a random part of 80 one bits, which has no successor: the specification calls that an error, and only a hand-built value reaches it.

fn bytes

fn bytes(): List<UInt8>

The sixteen bytes, most significant first.

fn show

fn show(): String

The twenty-six upper-case characters of Crockford base 32: two zero bits, then the 128 bits, five at a time.

fn compare

fn compare(other: Self): Ordering

In the order of the bytes, most significant first, which is the order of the text.

extend Ulid with TryFrom<String, IdentifierError>

extend Ulid with TryFrom<String, IdentifierError>

Twenty-six characters of Crockford base 32, upper or lower case: the alphabet is the digits and the letters but I, L, O and U, and none of Crockford's aliases for 1 and 0 is read. The first character is at most 7, because the text carries 130 bits and the identifier 128.

Errors

  • IdentifierError with expected a ULID for a wrong length, a character outside the alphabet or a first character above 7.

fn tryFrom

static fn tryFrom(text: String): Result<Self, IdentifierError>

extend String with From<Ulid>

extend String with From<Ulid>

The twenty-six characters of a ULID.

fn from

static fn from(value: Ulid): Self