package outpost import ( "crypto/rand" "encoding/base32" "time" ) // crockford is the Crockford base32 alphabet: no I, L, O, or U, so identifiers // read aloud unambiguously and compare case-insensitively. const crockford = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" var idEncoding = base32.NewEncoding(crockford).WithPadding(base32.NoPadding) // newID returns a 26-character identifier: 48 bits of millisecond timestamp // followed by 80 bits of randomness, encoded as Crockford base32. The timestamp // makes identifiers roughly sortable and readable in logs; uniqueness rests on // the 80 random bits. func newID() (string, error) { var b [16]byte ms := time.Now().UnixMilli() for i := 5; i >= 0; i-- { b[i] = byte(ms >> (8 * (5 - i))) } if _, err := rand.Read(b[6:]); err != nil { return "", err } return idEncoding.EncodeToString(b[:]), nil }