mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
pkg: remove random package
The unnecessary `random` package has been removed in favor of using the `math/rand` package directly. Seeding of the random value from crypto has been added to the `stringid` package to account for the change. May need to add an equivalent seed to `namesgenerator`, but this is often used with `stringid` and has collision protection. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
4b846a125b
commit
66cfe61f71
5 changed files with 32 additions and 111 deletions
|
@ -2,8 +2,7 @@ package namesgenerator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"github.com/docker/docker/pkg/random"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -594,15 +593,14 @@ var (
|
||||||
// formatted as "adjective_surname". For example 'focused_turing'. If retry is non-zero, a random
|
// formatted as "adjective_surname". For example 'focused_turing'. If retry is non-zero, a random
|
||||||
// integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3`
|
// integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3`
|
||||||
func GetRandomName(retry int) string {
|
func GetRandomName(retry int) string {
|
||||||
rnd := random.Rand
|
|
||||||
begin:
|
begin:
|
||||||
name := fmt.Sprintf("%s_%s", left[rnd.Intn(len(left))], right[rnd.Intn(len(right))])
|
name := fmt.Sprintf("%s_%s", left[rand.Intn(len(left))], right[rand.Intn(len(right))])
|
||||||
if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
|
if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
|
||||||
goto begin
|
goto begin
|
||||||
}
|
}
|
||||||
|
|
||||||
if retry > 0 {
|
if retry > 0 {
|
||||||
name = fmt.Sprintf("%s%d", name, rnd.Intn(10))
|
name = fmt.Sprintf("%s%d", name, rand.Intn(10))
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
package random
|
|
||||||
|
|
||||||
import (
|
|
||||||
cryptorand "crypto/rand"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Rand is a global *rand.Rand instance, which initialized with NewSource() source.
|
|
||||||
var Rand = rand.New(NewSource())
|
|
||||||
|
|
||||||
// Reader is a global, shared instance of a pseudorandom bytes generator.
|
|
||||||
// It doesn't consume entropy.
|
|
||||||
var Reader io.Reader = &reader{rnd: Rand}
|
|
||||||
|
|
||||||
// copypaste from standard 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSource returns math/rand.Source safe for concurrent use and initialized
|
|
||||||
// with current unix-nano timestamp
|
|
||||||
func NewSource() rand.Source {
|
|
||||||
var seed int64
|
|
||||||
if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
|
|
||||||
// This should not happen, but worst-case fallback to time-based seed.
|
|
||||||
seed = time.Now().UnixNano()
|
|
||||||
} else {
|
|
||||||
seed = cryptoseed.Int64()
|
|
||||||
}
|
|
||||||
return &lockedSource{
|
|
||||||
src: rand.NewSource(seed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type reader struct {
|
|
||||||
rnd *rand.Rand
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *reader) Read(b []byte) (int, error) {
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
val := r.rnd.Int63()
|
|
||||||
for val > 0 {
|
|
||||||
b[i] = byte(val)
|
|
||||||
i++
|
|
||||||
if i == len(b) {
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
val >>= 8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package random
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// for go test -v -race
|
|
||||||
func TestConcurrency(t *testing.T) {
|
|
||||||
rnd := rand.New(NewSource())
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
rnd.Int63()
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
|
@ -2,15 +2,17 @@
|
||||||
package stringid
|
package stringid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
cryptorand "crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
"github.com/docker/docker/pkg/random"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const shortLen = 12
|
const shortLen = 12
|
||||||
|
@ -39,12 +41,8 @@ func TruncateID(id string) string {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateID(crypto bool) string {
|
func generateID(r io.Reader) string {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
r := random.Reader
|
|
||||||
if crypto {
|
|
||||||
r = rand.Reader
|
|
||||||
}
|
|
||||||
for {
|
for {
|
||||||
if _, err := io.ReadFull(r, b); err != nil {
|
if _, err := io.ReadFull(r, b); err != nil {
|
||||||
panic(err) // This shouldn't happen
|
panic(err) // This shouldn't happen
|
||||||
|
@ -62,14 +60,14 @@ func generateID(crypto bool) string {
|
||||||
|
|
||||||
// GenerateRandomID returns a unique id.
|
// GenerateRandomID returns a unique id.
|
||||||
func GenerateRandomID() string {
|
func GenerateRandomID() string {
|
||||||
return generateID(true)
|
return generateID(cryptorand.Reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateNonCryptoID generates unique id without using cryptographically
|
// GenerateNonCryptoID generates unique id without using cryptographically
|
||||||
// secure sources of random.
|
// secure sources of random.
|
||||||
// It helps you to save entropy.
|
// It helps you to save entropy.
|
||||||
func GenerateNonCryptoID() string {
|
func GenerateNonCryptoID() string {
|
||||||
return generateID(false)
|
return generateID(readerFunc(rand.Read))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateID checks whether an ID string is a valid image ID.
|
// ValidateID checks whether an ID string is a valid image ID.
|
||||||
|
@ -79,3 +77,23 @@ func ValidateID(id string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// safely set the seed globally so we generate random ids. Tries to use a
|
||||||
|
// crypto seed before falling back to time.
|
||||||
|
var seed int64
|
||||||
|
if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
|
||||||
|
// This should not happen, but worst-case fallback to time-based seed.
|
||||||
|
seed = time.Now().UnixNano()
|
||||||
|
} else {
|
||||||
|
seed = cryptoseed.Int64()
|
||||||
|
}
|
||||||
|
|
||||||
|
rand.Seed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
type readerFunc func(p []byte) (int, error)
|
||||||
|
|
||||||
|
func (fn readerFunc) Read(p []byte) (int, error) {
|
||||||
|
return fn(p)
|
||||||
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/random"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerateRandomAlphaOnlyString generates an alphabetical random string with length n.
|
// GenerateRandomAlphaOnlyString generates an alphabetical random string with length n.
|
||||||
|
@ -15,7 +13,7 @@ func GenerateRandomAlphaOnlyString(n int) string {
|
||||||
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = letters[random.Rand.Intn(len(letters))]
|
b[i] = letters[rand.Intn(len(letters))]
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue