浏览代码

lib/rand: Various fixes (#6474)

greatroar 5 年之前
父节点
当前提交
c930b2e9e2
共有 3 个文件被更改,包括 13 次插入48 次删除
  1. 8 27
      lib/rand/random.go
  2. 0 17
      lib/rand/random_test.go
  3. 5 4
      lib/rand/securesource.go

+ 8 - 27
lib/rand/random.go

@@ -9,10 +9,7 @@
 package rand
 
 import (
-	"crypto/md5"
 	cryptoRand "crypto/rand"
-	"encoding/binary"
-	"io"
 	mathRand "math/rand"
 	"reflect"
 )
@@ -20,16 +17,16 @@ import (
 // Reader is the standard crypto/rand.Reader, re-exported for convenience
 var Reader = cryptoRand.Reader
 
-// randomCharset contains the characters that can make up a randomString().
+// randomCharset contains the characters that can make up a rand.String().
 const randomCharset = "2345679abcdefghijkmnopqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ"
 
 var (
 	// defaultSecureSource is a concurrency safe math/rand.Source with a
 	// cryptographically sound base.
-	defaltSecureSource = newSecureSource()
+	defaultSecureSource = newSecureSource()
 
 	// defaultSecureRand is a math/rand.Rand based on the secure source.
-	defaultSecureRand = mathRand.New(defaltSecureSource)
+	defaultSecureRand = mathRand.New(defaultSecureSource)
 )
 
 // String returns a strongly random string of characters (taken from
@@ -43,19 +40,14 @@ func String(l int) string {
 	return string(bs)
 }
 
-// Int63 returns a strongly random int63
+// Int63 returns a strongly random int63.
 func Int63() int64 {
-	return defaltSecureSource.Int63()
+	return defaultSecureSource.Int63()
 }
 
-// Int64 returns a strongly random int64
+// Int64 returns a strongly random int64.
 func Int64() int64 {
-	var bs [8]byte
-	_, err := io.ReadFull(cryptoRand.Reader, bs[:])
-	if err != nil {
-		panic("randomness failure: " + err.Error())
-	}
-	return int64(binary.BigEndian.Uint64(bs[:]))
+	return int64(defaultSecureSource.Uint64())
 }
 
 // Intn returns, as an int, a non-negative strongly random number in [0,n).
@@ -64,18 +56,7 @@ func Intn(n int) int {
 	return defaultSecureRand.Intn(n)
 }
 
-// SeedFromBytes calculates a weak 64 bit hash from the given byte slice,
-// suitable for use a predictable random seed.
-func SeedFromBytes(bs []byte) int64 {
-	h := md5.New()
-	h.Write(bs)
-	s := h.Sum(nil)
-	// The MD5 hash of the byte slice is 16 bytes long. We interpret it as two
-	// uint64s and XOR them together.
-	return int64(binary.BigEndian.Uint64(s[0:]) ^ binary.BigEndian.Uint64(s[8:]))
-}
-
-// Shuffle the order of elements
+// Shuffle the order of elements in slice.
 func Shuffle(slice interface{}) {
 	rv := reflect.ValueOf(slice)
 	swap := reflect.Swapper(slice)

+ 0 - 17
lib/rand/random_test.go

@@ -8,23 +8,6 @@ package rand
 
 import "testing"
 
-func TestSeedFromBytes(t *testing.T) {
-	// should always return the same seed for the same bytes
-	tcs := []struct {
-		bs []byte
-		v  int64
-	}{
-		{[]byte("hello world"), -3639725434188061933},
-		{[]byte("hello worlx"), -2539100776074091088},
-	}
-
-	for _, tc := range tcs {
-		if v := SeedFromBytes(tc.bs); v != tc.v {
-			t.Errorf("Unexpected seed value %d != %d", v, tc.v)
-		}
-	}
-}
-
 func TestRandomString(t *testing.T) {
 	for _, l := range []int{0, 1, 2, 3, 4, 8, 42} {
 		s := String(l)

+ 5 - 4
lib/rand/securesource.go

@@ -37,6 +37,10 @@ func (s *secureSource) Seed(int64) {
 }
 
 func (s *secureSource) Int63() int64 {
+	return int64(s.Uint64() & (1<<63 - 1))
+}
+
+func (s *secureSource) Uint64() uint64 {
 	var buf [8]byte
 
 	// Read eight bytes of entropy from the buffered, secure random number
@@ -50,8 +54,5 @@ func (s *secureSource) Int63() int64 {
 	}
 
 	// Grab those bytes as an uint64
-	v := binary.BigEndian.Uint64(buf[:])
-
-	// Mask of the high bit and return the resulting int63
-	return int64(v & (1<<63 - 1))
+	return binary.BigEndian.Uint64(buf[:])
 }