|
@@ -2,15 +2,17 @@
|
|
|
package stringid
|
|
|
|
|
|
import (
|
|
|
- "crypto/rand"
|
|
|
+ cryptorand "crypto/rand"
|
|
|
"encoding/hex"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
+ "math"
|
|
|
+ "math/big"
|
|
|
+ "math/rand"
|
|
|
"regexp"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
-
|
|
|
- "github.com/docker/docker/pkg/random"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
const shortLen = 12
|
|
@@ -39,12 +41,8 @@ func TruncateID(id string) string {
|
|
|
return id
|
|
|
}
|
|
|
|
|
|
-func generateID(crypto bool) string {
|
|
|
+func generateID(r io.Reader) string {
|
|
|
b := make([]byte, 32)
|
|
|
- r := random.Reader
|
|
|
- if crypto {
|
|
|
- r = rand.Reader
|
|
|
- }
|
|
|
for {
|
|
|
if _, err := io.ReadFull(r, b); err != nil {
|
|
|
panic(err) // This shouldn't happen
|
|
@@ -62,14 +60,14 @@ func generateID(crypto bool) string {
|
|
|
|
|
|
// GenerateRandomID returns a unique id.
|
|
|
func GenerateRandomID() string {
|
|
|
- return generateID(true)
|
|
|
+ return generateID(cryptorand.Reader)
|
|
|
}
|
|
|
|
|
|
// GenerateNonCryptoID generates unique id without using cryptographically
|
|
|
// secure sources of random.
|
|
|
// It helps you to save entropy.
|
|
|
func GenerateNonCryptoID() string {
|
|
|
- return generateID(false)
|
|
|
+ return generateID(readerFunc(rand.Read))
|
|
|
}
|
|
|
|
|
|
// ValidateID checks whether an ID string is a valid image ID.
|
|
@@ -79,3 +77,23 @@ func ValidateID(id string) error {
|
|
|
}
|
|
|
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)
|
|
|
+}
|