forked from inconshreveable/log15
/
id.go
47 lines (41 loc) · 1013 Bytes
/
id.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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()
}