random.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. // Package rand implements functions similar to math/rand in the standard
  7. // library, but on top of a secure random number generator.
  8. package rand
  9. import (
  10. cryptoRand "crypto/rand"
  11. mathRand "math/rand"
  12. "reflect"
  13. )
  14. // Reader is the standard crypto/rand.Reader, re-exported for convenience
  15. var Reader = cryptoRand.Reader
  16. // randomCharset contains the characters that can make up a rand.String().
  17. const randomCharset = "2345679abcdefghijkmnopqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ"
  18. var (
  19. // defaultSecureSource is a concurrency-safe, cryptographically secure
  20. // math/rand.Source.
  21. defaultSecureSource = newSecureSource()
  22. // defaultSecureRand is a math/rand.Rand based on the secure source.
  23. defaultSecureRand = mathRand.New(defaultSecureSource)
  24. )
  25. // String returns a cryptographically secure random string of characters
  26. // (taken from randomCharset) of the specified length. The returned string
  27. // contains ~5.8 bits of entropy per character, due to the character set used.
  28. func String(l int) string {
  29. bs := make([]byte, l)
  30. for i := range bs {
  31. bs[i] = randomCharset[defaultSecureRand.Intn(len(randomCharset))]
  32. }
  33. return string(bs)
  34. }
  35. // Int63 returns a cryptographically secure random int63.
  36. func Int63() int64 {
  37. return defaultSecureSource.Int63()
  38. }
  39. // Uint64 returns a cryptographically secure strongly random uint64.
  40. func Uint64() uint64 {
  41. return defaultSecureSource.Uint64()
  42. }
  43. // Intn returns, as an int, a cryptographically secure non-negative
  44. // random number in [0,n). It panics if n <= 0.
  45. func Intn(n int) int {
  46. return defaultSecureRand.Intn(n)
  47. }
  48. // Shuffle the order of elements in slice.
  49. func Shuffle(slice interface{}) {
  50. rv := reflect.ValueOf(slice)
  51. swap := reflect.Swapper(slice)
  52. length := rv.Len()
  53. if length < 2 {
  54. return
  55. }
  56. defaultSecureRand.Shuffle(length, swap)
  57. }