Implementing

TNID string

View this section in the spec ↗

Format

<name>.<encoded-data>
PartLengthContent
name1–4 (MUST)Name encoding characters, no nulls
.1Separator
encoded-data17 (MUST)Data encoding of the 102 data bits

19–22 characters in total:

test.Br2flcNDfF6LYICnT
└┬─┘│└───────┬───────┘
 │  │        └ encoded data (17 characters)
 │  └ separator
 └ name (1–4 characters)

Which bits go in the data

In the order they appear in the 128-bit value, skipping the constant UUID version and variant:

  1. The first 40 payload bits: the 28- and 12-bit runs.
  2. The 2 TNID variant bits.
  3. The last 60 payload bits.
nnnn.nnnn.nnnn.nnnn.nnnn.dddd.dddd.dddd-
dddd.dddd.dddd.dddd-
vvvv.dddd.dddd.dddd-
uudd.dddd.dddd.dddd-
dddd.dddd.dddd.dddd.dddd.dddd.dddd.dddd.dddd.dddd.dddd.dddd

n name, before the . · v UUID version, u UUID variant: not encoded · d data bits, encoded in order.

The TNID variant is the low 2 bits of data character 7 (string layout).

Parsing

  1. Split at the .; exactly one.
  2. Name: 1–4 characters, each in 0–4, a–z.
  3. Data: exactly 17 characters, each in the data alphabet.
  4. Encode the name into 20 bits, null-padded on the right.
  5. Decode the 17 characters into 102 bits d, most significant first.
  6. Assemble, with d[i..j] = bits i up to (not including) j:
id = name_bits      << 108
   | d[0..28]       << 80
   | 0x8            << 76    UUID version
   | d[28..40]      << 64
   | 0b10           << 62    UUID variant
   | d[40..102]              TNID variant (2 bits) + lower 60 payload bits

Formatting: name characters up to the first null, ., 17 data characters.

Case-sensitive: User.… is invalid, and …Br2f… and …BR2F… are different data.