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}