OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / tmlibs / common / random.go
1 package common
2
3 import (
4         crand "crypto/rand"
5         "math/rand"
6         "time"
7 )
8
9 const (
10         strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
11 )
12
13 func init() {
14         b := cRandBytes(8)
15         var seed uint64
16         for i := 0; i < 8; i++ {
17                 seed |= uint64(b[i])
18                 seed <<= 8
19         }
20         rand.Seed(int64(seed))
21 }
22
23 // Constructs an alphanumeric string of given length.
24 func RandStr(length int) string {
25         chars := []byte{}
26 MAIN_LOOP:
27         for {
28                 val := rand.Int63()
29                 for i := 0; i < 10; i++ {
30                         v := int(val & 0x3f) // rightmost 6 bits
31                         if v >= 62 {         // only 62 characters in strChars
32                                 val >>= 6
33                                 continue
34                         } else {
35                                 chars = append(chars, strChars[v])
36                                 if len(chars) == length {
37                                         break MAIN_LOOP
38                                 }
39                                 val >>= 6
40                         }
41                 }
42         }
43
44         return string(chars)
45 }
46
47 func RandUint16() uint16 {
48         return uint16(rand.Uint32() & (1<<16 - 1))
49 }
50
51 func RandUint32() uint32 {
52         return rand.Uint32()
53 }
54
55 func RandUint64() uint64 {
56         return uint64(rand.Uint32())<<32 + uint64(rand.Uint32())
57 }
58
59 func RandUint() uint {
60         return uint(rand.Int())
61 }
62
63 func RandInt16() int16 {
64         return int16(rand.Uint32() & (1<<16 - 1))
65 }
66
67 func RandInt32() int32 {
68         return int32(rand.Uint32())
69 }
70
71 func RandInt64() int64 {
72         return int64(rand.Uint32())<<32 + int64(rand.Uint32())
73 }
74
75 func RandInt() int {
76         return rand.Int()
77 }
78
79 // Distributed pseudo-exponentially to test for various cases
80 func RandUint16Exp() uint16 {
81         bits := rand.Uint32() % 16
82         if bits == 0 {
83                 return 0
84         }
85         n := uint16(1 << (bits - 1))
86         n += uint16(rand.Int31()) & ((1 << (bits - 1)) - 1)
87         return n
88 }
89
90 // Distributed pseudo-exponentially to test for various cases
91 func RandUint32Exp() uint32 {
92         bits := rand.Uint32() % 32
93         if bits == 0 {
94                 return 0
95         }
96         n := uint32(1 << (bits - 1))
97         n += uint32(rand.Int31()) & ((1 << (bits - 1)) - 1)
98         return n
99 }
100
101 // Distributed pseudo-exponentially to test for various cases
102 func RandUint64Exp() uint64 {
103         bits := rand.Uint32() % 64
104         if bits == 0 {
105                 return 0
106         }
107         n := uint64(1 << (bits - 1))
108         n += uint64(rand.Int63()) & ((1 << (bits - 1)) - 1)
109         return n
110 }
111
112 func RandFloat32() float32 {
113         return rand.Float32()
114 }
115
116 func RandTime() time.Time {
117         return time.Unix(int64(RandUint64Exp()), 0)
118 }
119
120 func RandBytes(n int) []byte {
121         bs := make([]byte, n)
122         for i := 0; i < n; i++ {
123                 bs[i] = byte(rand.Intn(256))
124         }
125         return bs
126 }
127
128 // NOTE: This relies on the os's random number generator.
129 // For real security, we should salt that with some seed.
130 // See github.com/tendermint/go-crypto for a more secure reader.
131 func cRandBytes(numBytes int) []byte {
132         b := make([]byte, numBytes)
133         _, err := crand.Read(b)
134         if err != nil {
135                 PanicCrisis(err)
136         }
137         return b
138 }