package ids import ( "crypto/rand" "crypto/sha256" "encoding/binary" "strings" ) const ( alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" randomLength = 11 ) type Prefix string const ( Project Prefix = "prj" Task Prefix = "tsk" Session Prefix = "ses" Snapshot Prefix = "snp" Review Prefix = "rev" InboxItem Prefix = "inb" InboxResponse Prefix = "rsp" Blob Prefix = "blb" LeadNote Prefix = "not" WorkflowDefinition Prefix = "wfd" WorkflowRun Prefix = "run" Send Prefix = "snd" Client Prefix = "cli" ClientRequest Prefix = "req" Transfer Prefix = "xfr" Terminal Prefix = "trm" SavedCommand Prefix = "cmd" ) func New(prefix Prefix) string { out := make([]byte, randomLength) buf := make([]byte, 1) for i := 0; i < len(out); { rand.Read(buf) if int(buf[0]) >= 256/len(alphabet)*len(alphabet) { continue } out[i] = alphabet[int(buf[0])%len(alphabet)] i++ } return string(prefix) + string(out) } func Derive(prefix Prefix, parts ...string) string { sum := sha256.Sum256([]byte(strings.Join(parts, "\x00"))) n := binary.BigEndian.Uint64(sum[:8]) out := make([]byte, randomLength) for i := range out { out[i] = alphabet[n%uint64(len(alphabet))] n /= uint64(len(alphabet)) } return string(prefix) + string(out) }