diff options
Diffstat (limited to 'vendor/github.com/pion/randutil/math.go')
-rw-r--r-- | vendor/github.com/pion/randutil/math.go | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/vendor/github.com/pion/randutil/math.go b/vendor/github.com/pion/randutil/math.go new file mode 100644 index 0000000..fbbf460 --- /dev/null +++ b/vendor/github.com/pion/randutil/math.go @@ -0,0 +1,72 @@ +package randutil + +import ( + mrand "math/rand" // used for non-crypto unique ID and random port selection + "sync" + "time" +) + +// MathRandomGenerator is a random generator for non-crypto usage. +type MathRandomGenerator interface { + // Intn returns random integer within [0:n). + Intn(n int) int + + // Uint32 returns random 32-bit unsigned integer. + Uint32() uint32 + + // Uint64 returns random 64-bit unsigned integer. + Uint64() uint64 + + // GenerateString returns ranom string using given set of runes. + // It can be used for generating unique ID to avoid name collision. + // + // Caution: DO NOT use this for cryptographic usage. + GenerateString(n int, runes string) string +} + +type mathRandomGenerator struct { + r *mrand.Rand + mu sync.Mutex +} + +// NewMathRandomGenerator creates new mathmatical random generator. +// Random generator is seeded by crypto random. +func NewMathRandomGenerator() MathRandomGenerator { + seed, err := CryptoUint64() + if err != nil { + // crypto/rand is unavailable. Fallback to seed by time. + seed = uint64(time.Now().UnixNano()) + } + + return &mathRandomGenerator{r: mrand.New(mrand.NewSource(int64(seed)))} +} + +func (g *mathRandomGenerator) Intn(n int) int { + g.mu.Lock() + v := g.r.Intn(n) + g.mu.Unlock() + return v +} + +func (g *mathRandomGenerator) Uint32() uint32 { + g.mu.Lock() + v := g.r.Uint32() + g.mu.Unlock() + return v +} + +func (g *mathRandomGenerator) Uint64() uint64 { + g.mu.Lock() + v := g.r.Uint64() + g.mu.Unlock() + return v +} + +func (g *mathRandomGenerator) GenerateString(n int, runes string) string { + letters := []rune(runes) + b := make([]rune, n) + for i := range b { + b[i] = letters[g.Intn(len(letters))] + } + return string(b) +} |