You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
5.8 KiB

9 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package common
  2. import (
  3. crand "crypto/rand"
  4. mrand "math/rand"
  5. "sync"
  6. "time"
  7. )
  8. const (
  9. strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
  10. )
  11. // pseudo random number generator.
  12. // seeded with OS randomness (crand)
  13. type Rand struct {
  14. sync.Mutex
  15. rand *mrand.Rand
  16. }
  17. var grand *Rand
  18. func init() {
  19. grand = NewRand()
  20. grand.init()
  21. }
  22. func NewRand() *Rand {
  23. rand := &Rand{}
  24. rand.init()
  25. return rand
  26. }
  27. func (r *Rand) init() {
  28. bz := cRandBytes(8)
  29. var seed uint64
  30. for i := 0; i < 8; i++ {
  31. seed |= uint64(bz[i])
  32. seed <<= 8
  33. }
  34. r.reset(int64(seed))
  35. }
  36. func (r *Rand) reset(seed int64) {
  37. r.rand = mrand.New(mrand.NewSource(seed))
  38. }
  39. //----------------------------------------
  40. // Global functions
  41. func Seed(seed int64) {
  42. grand.Seed(seed)
  43. }
  44. func RandStr(length int) string {
  45. return grand.Str(length)
  46. }
  47. func RandUint16() uint16 {
  48. return grand.Uint16()
  49. }
  50. func RandUint32() uint32 {
  51. return grand.Uint32()
  52. }
  53. func RandUint64() uint64 {
  54. return grand.Uint64()
  55. }
  56. func RandUint() uint {
  57. return grand.Uint()
  58. }
  59. func RandInt16() int16 {
  60. return grand.Int16()
  61. }
  62. func RandInt32() int32 {
  63. return grand.Int32()
  64. }
  65. func RandInt64() int64 {
  66. return grand.Int64()
  67. }
  68. func RandInt() int {
  69. return grand.Int()
  70. }
  71. func RandInt31() int32 {
  72. return grand.Int31()
  73. }
  74. func RandInt63() int64 {
  75. return grand.Int63()
  76. }
  77. func RandUint16Exp() uint16 {
  78. return grand.Uint16Exp()
  79. }
  80. func RandUint32Exp() uint32 {
  81. return grand.Uint32Exp()
  82. }
  83. func RandUint64Exp() uint64 {
  84. return grand.Uint64Exp()
  85. }
  86. func RandFloat32() float32 {
  87. return grand.Float32()
  88. }
  89. func RandTime() time.Time {
  90. return grand.Time()
  91. }
  92. func RandBytes(n int) []byte {
  93. return grand.Bytes(n)
  94. }
  95. func RandIntn(n int) int {
  96. return grand.Intn(n)
  97. }
  98. func RandPerm(n int) []int {
  99. return grand.Perm(n)
  100. }
  101. //----------------------------------------
  102. // Rand methods
  103. func (r *Rand) Seed(seed int64) {
  104. r.Lock()
  105. r.reset(seed)
  106. r.Unlock()
  107. }
  108. // Constructs an alphanumeric string of given length.
  109. // It is not safe for cryptographic usage.
  110. func (r *Rand) Str(length int) string {
  111. chars := []byte{}
  112. MAIN_LOOP:
  113. for {
  114. val := r.Int63()
  115. for i := 0; i < 10; i++ {
  116. v := int(val & 0x3f) // rightmost 6 bits
  117. if v >= 62 { // only 62 characters in strChars
  118. val >>= 6
  119. continue
  120. } else {
  121. chars = append(chars, strChars[v])
  122. if len(chars) == length {
  123. break MAIN_LOOP
  124. }
  125. val >>= 6
  126. }
  127. }
  128. }
  129. return string(chars)
  130. }
  131. // It is not safe for cryptographic usage.
  132. func (r *Rand) Uint16() uint16 {
  133. return uint16(r.Uint32() & (1<<16 - 1))
  134. }
  135. // It is not safe for cryptographic usage.
  136. func (r *Rand) Uint32() uint32 {
  137. r.Lock()
  138. u32 := r.rand.Uint32()
  139. r.Unlock()
  140. return u32
  141. }
  142. // It is not safe for cryptographic usage.
  143. func (r *Rand) Uint64() uint64 {
  144. return uint64(r.Uint32())<<32 + uint64(r.Uint32())
  145. }
  146. // It is not safe for cryptographic usage.
  147. func (r *Rand) Uint() uint {
  148. r.Lock()
  149. i := r.rand.Int()
  150. r.Unlock()
  151. return uint(i)
  152. }
  153. // It is not safe for cryptographic usage.
  154. func (r *Rand) Int16() int16 {
  155. return int16(r.Uint32() & (1<<16 - 1))
  156. }
  157. // It is not safe for cryptographic usage.
  158. func (r *Rand) Int32() int32 {
  159. return int32(r.Uint32())
  160. }
  161. // It is not safe for cryptographic usage.
  162. func (r *Rand) Int64() int64 {
  163. return int64(r.Uint64())
  164. }
  165. // It is not safe for cryptographic usage.
  166. func (r *Rand) Int() int {
  167. r.Lock()
  168. i := r.rand.Int()
  169. r.Unlock()
  170. return i
  171. }
  172. // It is not safe for cryptographic usage.
  173. func (r *Rand) Int31() int32 {
  174. r.Lock()
  175. i31 := r.rand.Int31()
  176. r.Unlock()
  177. return i31
  178. }
  179. // It is not safe for cryptographic usage.
  180. func (r *Rand) Int63() int64 {
  181. r.Lock()
  182. i63 := r.rand.Int63()
  183. r.Unlock()
  184. return i63
  185. }
  186. // Distributed pseudo-exponentially to test for various cases
  187. // It is not safe for cryptographic usage.
  188. func (r *Rand) Uint16Exp() uint16 {
  189. bits := r.Uint32() % 16
  190. if bits == 0 {
  191. return 0
  192. }
  193. n := uint16(1 << (bits - 1))
  194. n += uint16(r.Int31()) & ((1 << (bits - 1)) - 1)
  195. return n
  196. }
  197. // Distributed pseudo-exponentially to test for various cases
  198. // It is not safe for cryptographic usage.
  199. func (r *Rand) Uint32Exp() uint32 {
  200. bits := r.Uint32() % 32
  201. if bits == 0 {
  202. return 0
  203. }
  204. n := uint32(1 << (bits - 1))
  205. n += uint32(r.Int31()) & ((1 << (bits - 1)) - 1)
  206. return n
  207. }
  208. // Distributed pseudo-exponentially to test for various cases
  209. // It is not safe for cryptographic usage.
  210. func (r *Rand) Uint64Exp() uint64 {
  211. bits := r.Uint32() % 64
  212. if bits == 0 {
  213. return 0
  214. }
  215. n := uint64(1 << (bits - 1))
  216. n += uint64(r.Int63()) & ((1 << (bits - 1)) - 1)
  217. return n
  218. }
  219. // It is not safe for cryptographic usage.
  220. func (r *Rand) Float32() float32 {
  221. r.Lock()
  222. f32 := r.rand.Float32()
  223. r.Unlock()
  224. return f32
  225. }
  226. // It is not safe for cryptographic usage.
  227. func (r *Rand) Time() time.Time {
  228. return time.Unix(int64(r.Uint64Exp()), 0)
  229. }
  230. // RandBytes returns n random bytes from the OS's source of entropy ie. via crypto/rand.
  231. // It is not safe for cryptographic usage.
  232. func (r *Rand) Bytes(n int) []byte {
  233. // cRandBytes isn't guaranteed to be fast so instead
  234. // use random bytes generated from the internal PRNG
  235. bs := make([]byte, n)
  236. for i := 0; i < len(bs); i++ {
  237. bs[i] = byte(r.Int() & 0xFF)
  238. }
  239. return bs
  240. }
  241. // RandIntn returns, as an int, a non-negative pseudo-random number in [0, n).
  242. // It panics if n <= 0.
  243. // It is not safe for cryptographic usage.
  244. func (r *Rand) Intn(n int) int {
  245. r.Lock()
  246. i := r.rand.Intn(n)
  247. r.Unlock()
  248. return i
  249. }
  250. // RandPerm returns a pseudo-random permutation of n integers in [0, n).
  251. // It is not safe for cryptographic usage.
  252. func (r *Rand) Perm(n int) []int {
  253. r.Lock()
  254. perm := r.rand.Perm(n)
  255. r.Unlock()
  256. return perm
  257. }
  258. // NOTE: This relies on the os's random number generator.
  259. // For real security, we should salt that with some seed.
  260. // See github.com/tendermint/go-crypto for a more secure reader.
  261. func cRandBytes(numBytes int) []byte {
  262. b := make([]byte, numBytes)
  263. _, err := crand.Read(b)
  264. if err != nil {
  265. PanicCrisis(err)
  266. }
  267. return b
  268. }