string.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package utils
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "errors"
  8. r "math/rand"
  9. "time"
  10. )
  11. func AESGCMEncrypt(key, plaintext []byte) ([]byte, error) {
  12. block, err := aes.NewCipher(key)
  13. if err != nil {
  14. return nil, err
  15. }
  16. gcm, err := cipher.NewGCM(block)
  17. if err != nil {
  18. return nil, err
  19. }
  20. nonce := make([]byte, gcm.NonceSize())
  21. if _, err := rand.Read(nonce); err != nil {
  22. return nil, err
  23. }
  24. ciphertext := gcm.Seal(nil, nonce, plaintext, nil)
  25. return append(nonce, ciphertext...), nil
  26. }
  27. // AESGCMDecrypt decrypts ciphertext with the given key using AES in GCM mode.
  28. func AESGCMDecrypt(key, ciphertext []byte) ([]byte, error) {
  29. block, err := aes.NewCipher(key)
  30. if err != nil {
  31. return nil, err
  32. }
  33. gcm, err := cipher.NewGCM(block)
  34. if err != nil {
  35. return nil, err
  36. }
  37. size := gcm.NonceSize()
  38. if len(ciphertext)-size <= 0 {
  39. return nil, errors.New("Ciphertext is empty")
  40. }
  41. nonce := ciphertext[:size]
  42. ciphertext = ciphertext[size:]
  43. plainText, err := gcm.Open(nil, nonce, ciphertext, nil)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return plainText, nil
  48. }
  49. func UrlEncode(data string) string {
  50. return base64.URLEncoding.EncodeToString([]byte(data))
  51. }
  52. func UrlDecode(data string) (string, error) {
  53. res, err := base64.URLEncoding.DecodeString(data)
  54. if err != nil {
  55. return "", err
  56. }
  57. return string(res), nil
  58. }
  59. const (
  60. RAND_KIND_NUM = 0 // 纯数字
  61. RAND_KIND_LOWER = 1 // 小写字母
  62. RAND_KIND_UPPER = 2 // 大写字母
  63. RAND_KIND_ALL = 3 // 数字、大小写字母
  64. )
  65. func RandomStr() string {
  66. return ToStr(time.Now().UnixNano()) + string(RandomCreateBytes(10, RAND_KIND_NUM))
  67. }
  68. func RandomOrder(prefix string, randomSize int) string {
  69. return prefix + DateT(time.Now(), "YYMMDDHHmmss") + ToStr(time.Now().UnixNano())[10:12] + string(RandomCreateBytes(randomSize, RAND_KIND_NUM))
  70. }
  71. // RandomCreateBytes generate random []byte by specify chars.
  72. func RandomCreateBytes(n int, kind int, alphabets ...byte) []byte {
  73. var alphanum = ""
  74. switch kind {
  75. case RAND_KIND_NUM:
  76. alphanum = "0123456789"
  77. case RAND_KIND_LOWER:
  78. alphanum = "abcdefghijklmnopqrstuvwxyz"
  79. case RAND_KIND_UPPER:
  80. alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  81. case RAND_KIND_ALL:
  82. alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  83. }
  84. var bytes = make([]byte, n)
  85. var randby bool
  86. if num, err := rand.Read(bytes); num != n || err != nil {
  87. r.Seed(time.Now().UnixNano())
  88. randby = true
  89. }
  90. for i, b := range bytes {
  91. if len(alphabets) == 0 {
  92. if randby {
  93. bytes[i] = alphanum[r.Intn(len(alphanum))]
  94. } else {
  95. bytes[i] = alphanum[b%byte(len(alphanum))]
  96. }
  97. } else {
  98. if randby {
  99. bytes[i] = alphabets[r.Intn(len(alphabets))]
  100. } else {
  101. bytes[i] = alphabets[b%byte(len(alphabets))]
  102. }
  103. }
  104. }
  105. return bytes
  106. }
  107. func SubStr(str string, start int, length int) (result string) {
  108. s := []rune(str)
  109. total := len(s)
  110. if total == 0 {
  111. return
  112. }
  113. // 允许从尾部开始计算
  114. if start < 0 {
  115. start = total + start
  116. if start < 0 {
  117. return
  118. }
  119. }
  120. if start > total {
  121. return
  122. }
  123. // 到末尾
  124. if length < 0 {
  125. length = total
  126. }
  127. end := start + length
  128. if end > total {
  129. result = string(s[start:])
  130. } else {
  131. result = string(s[start:end])
  132. }
  133. return
  134. }