48 lines
1013 B
Go
48 lines
1013 B
Go
package ext
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var r = rand.New(&lockedSource{src: rand.NewSource(time.Now().Unix())})
|
|
|
|
// RandId creates a random identifier of the requested length.
|
|
// Useful for assigning mostly-unique identifiers for logging
|
|
// and identification that are unlikely to collide because of
|
|
// short lifespan or low set cardinality
|
|
func RandId(idlen int) string {
|
|
b := make([]byte, idlen)
|
|
var randVal uint32
|
|
for i := 0; i < idlen; i++ {
|
|
byteIdx := i % 4
|
|
if byteIdx == 0 {
|
|
randVal = r.Uint32()
|
|
}
|
|
b[i] = byte((randVal >> (8 * uint(byteIdx))) & 0xFF)
|
|
}
|
|
return fmt.Sprintf("%x", b)
|
|
}
|
|
|
|
// lockedSource is a wrapper to allow a rand.Source to be used
|
|
// concurrently (same type as the one used internally in math/rand).
|
|
type lockedSource struct {
|
|
lk sync.Mutex
|
|
src rand.Source
|
|
}
|
|
|
|
func (r *lockedSource) Int63() (n int64) {
|
|
r.lk.Lock()
|
|
n = r.src.Int63()
|
|
r.lk.Unlock()
|
|
return
|
|
}
|
|
|
|
func (r *lockedSource) Seed(seed int64) {
|
|
r.lk.Lock()
|
|
r.src.Seed(seed)
|
|
r.lk.Unlock()
|
|
}
|