tid.go
1// Package tid generates ATProto TIDs: 13-character, base32-sortable record
2// keys from a microsecond timestamp and a 10-bit clock id. Used for record
3// keys and local run ids.
4package tid
5
6import (
7 "math/rand/v2"
8 "sync"
9 "time"
10)
11
12const alphabet = "234567abcdefghijklmnopqrstuvwxyz"
13
14var (
15 mu sync.Mutex
16 last int64
17 clockID = rand.Int64N(1024)
18)
19
20// New returns a TID greater than any previously returned by this process.
21func New() string {
22 mu.Lock()
23 us := time.Now().UnixMicro()
24 if us <= last {
25 us = last + 1
26 }
27 last = us
28 mu.Unlock()
29 return Encode(us, clockID)
30}
31
32// Encode formats a TID from microseconds since the epoch and a clock id.
33func Encode(us, clock int64) string {
34 v := uint64(us&(1<<53-1))<<10 | uint64(clock&1023)
35 var b [13]byte
36 for i := 12; i >= 0; i-- {
37 b[i] = alphabet[v&31]
38 v >>= 5
39 }
40 return string(b[:])
41}