1package ext 2 3import ( 4 "fmt" 5 "math/rand" 6 "sync" 7 "time" 8) 9 10var r = rand.New(&lockedSource{src: rand.NewSource(time.Now().Unix())}) 11 12// RandId creates a random identifier of the requested length. 13// Useful for assigning mostly-unique identifiers for logging 14// and identification that are unlikely to collide because of 15// short lifespan or low set cardinality 16func RandId(idlen int) string { 17 b := make([]byte, idlen) 18 var randVal uint32 19 for i := 0; i < idlen; i++ { 20 byteIdx := i % 4 21 if byteIdx == 0 { 22 randVal = r.Uint32() 23 } 24 b[i] = byte((randVal >> (8 * uint(byteIdx))) & 0xFF) 25 } 26 return fmt.Sprintf("%x", b) 27} 28 29// lockedSource is a wrapper to allow a rand.Source to be used 30// concurrently (same type as the one used internally in math/rand). 31type lockedSource struct { 32 lk sync.Mutex 33 src rand.Source 34} 35 36func (r *lockedSource) Int63() (n int64) { 37 r.lk.Lock() 38 n = r.src.Int63() 39 r.lk.Unlock() 40 return 41} 42 43func (r *lockedSource) Seed(seed int64) { 44 r.lk.Lock() 45 r.src.Seed(seed) 46 r.lk.Unlock() 47} 48