| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // Copyright (C) 2014 The Syncthing Authors.
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
- // You can obtain one at https://mozilla.org/MPL/2.0/.
- // Package rand implements functions similar to math/rand in the standard
- // library, but on top of a secure random number generator.
- package rand
- import (
- cryptoRand "crypto/rand"
- mathRand "math/rand"
- "reflect"
- )
- // Reader is the standard crypto/rand.Reader, re-exported for convenience
- var Reader = cryptoRand.Reader
- // 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.
- defaultSecureSource = newSecureSource()
- // defaultSecureRand is a math/rand.Rand based on the secure source.
- defaultSecureRand = mathRand.New(defaultSecureSource)
- )
- // String returns a strongly random string of characters (taken from
- // randomCharset) of the specified length. The returned string contains ~5.8
- // bits of entropy per character, due to the character set used.
- func String(l int) string {
- bs := make([]byte, l)
- for i := range bs {
- bs[i] = randomCharset[defaultSecureRand.Intn(len(randomCharset))]
- }
- return string(bs)
- }
- // Int63 returns a strongly random int63.
- func Int63() int64 {
- return defaultSecureSource.Int63()
- }
- // Int64 returns a strongly random int64.
- func Int64() int64 {
- return int64(defaultSecureSource.Uint64())
- }
- // Intn returns, as an int, a non-negative strongly random number in [0,n).
- // It panics if n <= 0.
- func Intn(n int) int {
- return defaultSecureRand.Intn(n)
- }
- // Shuffle the order of elements in slice.
- func Shuffle(slice interface{}) {
- rv := reflect.ValueOf(slice)
- swap := reflect.Swapper(slice)
- length := rv.Len()
- if length < 2 {
- return
- }
- defaultSecureRand.Shuffle(length, swap)
- }
|