random.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Package random provides utilities for generating random strings and numbers.
  2. package random
  3. import (
  4. "crypto/rand"
  5. "encoding/base64"
  6. "math/big"
  7. )
  8. var (
  9. numSeq [10]rune
  10. lowerSeq [26]rune
  11. upperSeq [26]rune
  12. numLowerSeq [36]rune
  13. numUpperSeq [36]rune
  14. allSeq [62]rune
  15. )
  16. // init initializes the character sequences used for random string generation.
  17. // It sets up arrays for numbers, lowercase letters, uppercase letters, and combinations.
  18. func init() {
  19. for i := range 10 {
  20. numSeq[i] = rune('0' + i)
  21. }
  22. for i := range 26 {
  23. lowerSeq[i] = rune('a' + i)
  24. upperSeq[i] = rune('A' + i)
  25. }
  26. copy(numLowerSeq[:], numSeq[:])
  27. copy(numLowerSeq[len(numSeq):], lowerSeq[:])
  28. copy(numUpperSeq[:], numSeq[:])
  29. copy(numUpperSeq[len(numSeq):], upperSeq[:])
  30. copy(allSeq[:], numSeq[:])
  31. copy(allSeq[len(numSeq):], lowerSeq[:])
  32. copy(allSeq[len(numSeq)+len(lowerSeq):], upperSeq[:])
  33. }
  34. // Seq generates a random string of length n containing alphanumeric characters (numbers, lowercase and uppercase letters).
  35. func Seq(n int) string {
  36. runes := make([]rune, n)
  37. for i := range n {
  38. idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(allSeq))))
  39. if err != nil {
  40. panic("crypto/rand failed: " + err.Error())
  41. }
  42. runes[i] = allSeq[idx.Int64()]
  43. }
  44. return string(runes)
  45. }
  46. // NumLower generates a random string of length n containing digits and lowercase letters only.
  47. func NumLower(n int) string {
  48. runes := make([]rune, n)
  49. for i := range n {
  50. idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(numLowerSeq))))
  51. if err != nil {
  52. panic("crypto/rand failed: " + err.Error())
  53. }
  54. runes[i] = numLowerSeq[idx.Int64()]
  55. }
  56. return string(runes)
  57. }
  58. // Num generates a random integer between 0 and n-1.
  59. func Num(n int) int {
  60. bn := big.NewInt(int64(n))
  61. r, err := rand.Int(rand.Reader, bn)
  62. if err != nil {
  63. panic("crypto/rand failed: " + err.Error())
  64. }
  65. return int(r.Int64())
  66. }
  67. // Base64Bytes returns n cryptographically-random bytes encoded as standard
  68. // base64 (with padding). Used for ss2022 keys, which xray expects as a
  69. // base64-encoded key of a specific byte length per cipher.
  70. func Base64Bytes(n int) string {
  71. b := make([]byte, n)
  72. if _, err := rand.Read(b); err != nil {
  73. panic("crypto/rand failed: " + err.Error())
  74. }
  75. return base64.StdEncoding.EncodeToString(b)
  76. }