util.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package util
  2. import (
  3. "bytes"
  4. srand "crypto/rand"
  5. "encoding/binary"
  6. "math/rand"
  7. "net/http"
  8. "net/url"
  9. "sort"
  10. "time"
  11. )
  12. const dictionary = "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  13. //CreateRandomString create random string
  14. func CreateRandomString() string {
  15. b := make([]byte, 32)
  16. l := len(dictionary)
  17. _, err := srand.Read(b)
  18. if err != nil {
  19. // fail back to insecure rand
  20. rand.Seed(time.Now().UnixNano())
  21. for i := range b {
  22. b[i] = dictionary[rand.Int()%l]
  23. }
  24. } else {
  25. for i, v := range b {
  26. b[i] = dictionary[v%byte(l)]
  27. }
  28. }
  29. return string(b)
  30. }
  31. // Encode encodes the values into ``URL encoded'' form
  32. // ("acl&bar=baz&foo=quux") sorted by key.
  33. func Encode(v url.Values) string {
  34. if v == nil {
  35. return ""
  36. }
  37. var buf bytes.Buffer
  38. keys := make([]string, 0, len(v))
  39. for k := range v {
  40. keys = append(keys, k)
  41. }
  42. sort.Strings(keys)
  43. for _, k := range keys {
  44. vs := v[k]
  45. prefix := url.QueryEscape(k)
  46. for _, v := range vs {
  47. if buf.Len() > 0 {
  48. buf.WriteByte('&')
  49. }
  50. buf.WriteString(prefix)
  51. if v != "" {
  52. buf.WriteString("=")
  53. buf.WriteString(url.QueryEscape(v))
  54. }
  55. }
  56. }
  57. return buf.String()
  58. }
  59. func GetGMTime() string {
  60. return time.Now().UTC().Format(http.TimeFormat)
  61. }
  62. //
  63. func randUint32() uint32 {
  64. return randUint32Slice(1)[0]
  65. }
  66. func randUint32Slice(c int) []uint32 {
  67. b := make([]byte, c*4)
  68. _, err := srand.Read(b)
  69. if err != nil {
  70. // fail back to insecure rand
  71. rand.Seed(time.Now().UnixNano())
  72. for i := range b {
  73. b[i] = byte(rand.Int())
  74. }
  75. }
  76. n := make([]uint32, c)
  77. for i := range n {
  78. n[i] = binary.BigEndian.Uint32(b[i*4 : i*4+4])
  79. }
  80. return n
  81. }
  82. func toByte(n uint32, st, ed byte) byte {
  83. return byte(n%uint32(ed-st+1) + uint32(st))
  84. }
  85. func toDigit(n uint32) byte {
  86. return toByte(n, '0', '9')
  87. }
  88. func toLowerLetter(n uint32) byte {
  89. return toByte(n, 'a', 'z')
  90. }
  91. func toUpperLetter(n uint32) byte {
  92. return toByte(n, 'A', 'Z')
  93. }
  94. type convFunc func(uint32) byte
  95. var convFuncs = []convFunc{toDigit, toLowerLetter, toUpperLetter}
  96. // tools for generating a random ECS instance password
  97. // from 8 to 30 char MUST contain digit upper, case letter and upper case letter
  98. // http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
  99. func GenerateRandomECSPassword() string {
  100. // [8, 30]
  101. l := int(randUint32()%23 + 8)
  102. n := randUint32Slice(l)
  103. b := make([]byte, l)
  104. b[0] = toDigit(n[0])
  105. b[1] = toLowerLetter(n[1])
  106. b[2] = toUpperLetter(n[2])
  107. for i := 3; i < l; i++ {
  108. b[i] = convFuncs[n[i]%3](n[i])
  109. }
  110. s := make([]byte, l)
  111. perm := rand.Perm(l)
  112. for i, v := range perm {
  113. s[v] = b[i]
  114. }
  115. return string(s)
  116. }