Test vectors
From the Rust reference implementation (tnid 0.2.0), cross-checked against an independent implementation written from the spec, which has no vectors. Encryption vectors are the TypeScript library's Rust-compatibility tests. All in test-vectors.json.
Fields: ms decimal; random, payload, key hex; uuid lowercase UUID form; payload is the 100-bit value in bit layout order.
Names
| Name | 20-bit value (hex) |
|---|---|
a | 30000 |
0 | 08000 |
ab | 31c00 |
a1b2 | 308e3 |
post | ad319 |
test | cab19 |
user | d6157 |
zzzz | fffff |
Variant 0
Inputs: name, milliseconds since the Unix epoch, 57 random bits.
name a
ms 0
random 0
string a.-----------------
uuid 30000000-0000-8000-8000-000000000000
name user
ms 1234567890
random 0
string user.--Zmk4cF---------
uuid d6157000-932c-805a-8400-000000000000
name test
ms 1767502656561
random 123456789abcde
string test.Br2flcN7HC4OsafnT
uuid cab19337-0ebc-8686-8212-3456789abcde
name zzzz
ms 8796093022207
random 1ffffffffffffff
string zzzz.zzzzzzwzzzzzzzzzz
uuid ffffffff-ffff-8fff-8fff-ffffffffffff8796093022207 = 2⁴³ − 1, the largest timestamp.
Timestamp wrap
Timestamps past 2⁴³ − 1 SHOULD wrap: 9999999999999 mod 2⁴³ = 1203906977791.
name post
ms 9999999999999 (stored as 1203906977791)
random 154a98ceb1f0ad2
string post.7kbDJzwxJeNnf6kfH
uuid ad319230-9ce5-83ff-8f54-a98ceb1f0ad2Variant 1
Inputs: name, 100-bit payload.
name a
payload 0
string a.------0----------
uuid 30000000-0000-8000-9000-000000000000
name b
payload 1
string b.------0---------0
uuid 38000000-0000-8000-9000-000000000001
name test
payload 123456789abcdef0123456789
string test.3YGLT8djCvk3YGLT8
uuid cab19123-4567-889a-9bcd-ef0123456789
name zzzz
payload fffffffffffffffffffffffff
string zzzz.zzzzzzxzzzzzzzzzz
uuid ffffffff-ffff-8fff-9fff-ffffffffffffRound trips
Each pair is one TNID; parsing either side gives the other.
string test.x8MRU0xetVa6QZeZR
uuid cab19f49-5dc7-8c1f-9ab9-8261db92a91c
variant 1
string user.Br2flcNDfF6LYICnT
uuid d6157337-0ebc-8686-83ab-4075a34cdcde
variant 0
string user.BsOdOgguzJorJeVH7
uuid d6157338-6696-86cb-8ebf-534dd4aa0488
variant 0
string user.Br2flcPDfF6LYICnT
uuid d6157337-0ebc-8686-a3ab-4075a34cdcde
variant 2 (reserved)
string user.Br2flcQDfF6LYICnT
uuid d6157337-0ebc-8686-b3ab-4075a34cdcde
variant 3 (reserved)Parsers SHOULD accept the reserved variants 2 and 3. UUID input is case-insensitive: D6157337-0EBC-8686-83AB-4075A34CDCDE parses to user.Br2flcNDfF6LYICnT.
Must reject
Required by the spec's MUST rules, and for UUID form by RFC 9562, which the spec defers to.
| TNID string | Reason |
|---|---|
User.Br2flcNDfF6LYICnT | Uppercase in the name |
users.Br2flcNDfF6LYICnT | Name longer than 4 |
5.Br2flcNDfF6LYICnT | 5 not in the name alphabet |
.Br2flcNDfF6LYICnT | Empty name |
user.Br2flcNDfF6LYICn | 16 data characters |
user.Br2flcNDfF6LYICnTx | 18 data characters |
user.Br2flcNDfF6LYIC+T | + not in the data alphabet |
user.Br2flcNDfF6LY.CnT | Two dots; data is 17 characters, but . is not in the data alphabet |
user. | Empty data |
user.Br2flcNDfF6LYICnT with a leading space or trailing newline | Whitespace: reject, don't trim |
usér.Br2flcNDfF6LYICnT | é not in the name alphabet (4 code points long) |
user.Br2flcNDfF6LYICnТ | Last character is Cyrillic Т (U+0422), not ASCII T |
| UUID | Reason |
|---|---|
d6157337-0ebc-8686-83ab-4075a34cdcd | 31 hex digits |
d6157337-0ebc-8686-83ab-4075a34cdcde0 | 33 hex digits |
d6157337-0ebc-4686-83ab-4075a34cdcde | UUID version 4 |
d6157337-0ebc-9686-83ab-4075a34cdcde | UUID version 9 |
d6157337-0ebc-8686-c3ab-4075a34cdcde | UUID variant 0b11 |
00000000-0000-8000-8000-000000000000 | All-null name |
300e0000-0000-8000-8000-000000000000 | Name a, null, b, null: character after a null |
tnid 0.2.0 checks only the high bit of the version and variant fields, so it accepts the version 9 and variant 0b11 inputs. Check for exact equality.
Left open by the spec
Tests should allow accepting or rejecting them. tnid 0.2.0 rejects all three. A parser that accepts one outputs the lowercase, hyphenated UUID form.
| Input | Form |
|---|---|
d61573370ebc868683ab4075a34cdcde | No hyphens |
{d6157337-0ebc-8686-83ab-4075a34cdcde} | Braces |
urn:uuid:d6157337-0ebc-8686-83ab-4075a34cdcde | URN prefix |
Encryption
V0/V1 encryption: encrypting v0 with key gives v1; decrypting v1 gives v0.
key 00000000000000000000000000000000
v0 a.-----------------
v1 a.qjrH3l_XfqYmAVUgO
key 0102030405060708090a0b0c0d0e0f10
v0 user.--Zmk4cF---------
v1 user.S1PcM9daFtzp1lJM5
key 0102030405060708090a0b0c0d0e0f10
v0 user.BsOdOgguzJorJeVH7
v1 user.-8hAMlKY0mjrmzQHv
key 2b7e151628aed2a6abf7158809cf4f3c
v0 post.7kbDJzwxJeNnf6kfH
v1 post.X3Wxwp0wOy4OZp_rPBlocklist filtering is non-deterministic and has no vectors: check that generated TNIDs never contain a blocklisted pattern, in any case.