package controlapi import ( "crypto/rand" "encoding/hex" "errors" "math/big" "time" ) const crockford = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" func newULID(prefix string, now time.Time) (string, error) { value := make([]byte, 16) milliseconds := uint64(now.UTC().UnixMilli()) value[0] = byte(milliseconds >> 40) value[1] = byte(milliseconds >> 32) value[2] = byte(milliseconds >> 24) value[3] = byte(milliseconds >> 16) value[4] = byte(milliseconds >> 8) value[5] = byte(milliseconds) if _, err := rand.Read(value[6:]); err != nil { return "", errors.New("generate identifier randomness") } number := new(big.Int).SetBytes(value) base := big.NewInt(32) remainder := new(big.Int) encoded := make([]byte, 26) for index := len(encoded) - 1; index >= 0; index-- { number.QuoRem(number, base, remainder) encoded[index] = crockford[remainder.Int64()] } return prefix + string(encoded), nil } func newTraceID() (string, error) { value := make([]byte, 16) if _, err := rand.Read(value); err != nil { return "", errors.New("generate trace identifier") } return "trace_" + hex.EncodeToString(value), nil }