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.

63 lines
1.2 KiB

  1. package common
  2. import (
  3. crand "crypto/rand"
  4. "encoding/hex"
  5. "math/rand"
  6. )
  7. const (
  8. strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
  9. )
  10. func init() {
  11. // Seed math/rand with "secure" int64
  12. b := RandBytes(8)
  13. var seed uint64
  14. for i := 0; i < 8; i++ {
  15. seed |= uint64(b[i])
  16. seed <<= 8
  17. }
  18. rand.Seed(int64(seed))
  19. }
  20. // Constructs an alphanumeric string of given length.
  21. // Not crypto safe
  22. func RandStr(length int) string {
  23. chars := []byte{}
  24. MAIN_LOOP:
  25. for {
  26. val := rand.Int63()
  27. for i := 0; i < 10; i++ {
  28. v := int(val & 0x3f) // rightmost 6 bits
  29. if v >= 62 { // only 62 characters in strChars
  30. val >>= 6
  31. continue
  32. } else {
  33. chars = append(chars, strChars[v])
  34. if len(chars) == length {
  35. break MAIN_LOOP
  36. }
  37. val >>= 6
  38. }
  39. }
  40. }
  41. return string(chars)
  42. }
  43. // Crypto safe
  44. func RandBytes(numBytes int) []byte {
  45. b := make([]byte, numBytes)
  46. _, err := crand.Read(b)
  47. if err != nil {
  48. panic(err)
  49. }
  50. return b
  51. }
  52. // Crypto safe
  53. // RandHex(24) gives 96 bits of randomness, strong enough for most purposes.
  54. func RandHex(numDigits int) string {
  55. return hex.EncodeToString(RandBytes(numDigits / 2))
  56. }