tendermint/common/random.go

64 lines
1.2 KiB
Go
Raw Normal View History

package common
2014-07-15 23:41:40 -07:00
import (
2014-07-16 17:23:13 -07:00
crand "crypto/rand"
"encoding/hex"
2014-07-15 23:41:40 -07:00
"math/rand"
)
2014-07-15 23:41:40 -07:00
const (
strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
)
2014-07-16 17:23:13 -07:00
func init() {
// Seed math/rand with "secure" int64
b := RandBytes(8)
var seed uint64
for i := 0; i < 8; i++ {
seed |= uint64(b[i])
seed <<= 8
}
rand.Seed(int64(seed))
}
// Constructs an alphanumeric string of given length.
// Not crypto safe
func RandStr(length int) string {
2014-07-15 23:41:40 -07:00
chars := []byte{}
MAIN_LOOP:
for {
val := rand.Int63()
for i := 0; i < 10; i++ {
v := int(val & 0x3f) // rightmost 6 bits
if v >= 62 { // only 62 characters in strChars
val >>= 6
continue
} else {
chars = append(chars, strChars[v])
if len(chars) == length {
break MAIN_LOOP
}
val >>= 6
}
}
}
2014-07-15 23:41:40 -07:00
return string(chars)
}
2014-07-16 17:23:13 -07:00
// Crypto safe
func RandBytes(numBytes int) []byte {
b := make([]byte, numBytes)
_, err := crand.Read(b)
if err != nil {
panic(err)
}
return b
}
// Crypto safe
// RandHex(24) gives 96 bits of randomness, strong enough for most purposes.
func RandHex(numDigits int) string {
return hex.EncodeToString(RandBytes(numDigits / 2))
}