str.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package common
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "math/rand"
  6. "net/url"
  7. "regexp"
  8. "strconv"
  9. "strings"
  10. "unsafe"
  11. )
  12. func GetStringIfEmpty(str string, defaultValue string) string {
  13. if str == "" {
  14. return defaultValue
  15. }
  16. return str
  17. }
  18. func GetRandomString(length int) string {
  19. //rand.Seed(time.Now().UnixNano())
  20. key := make([]byte, length)
  21. for i := 0; i < length; i++ {
  22. key[i] = keyChars[rand.Intn(len(keyChars))]
  23. }
  24. return string(key)
  25. }
  26. func MapToJsonStr(m map[string]interface{}) string {
  27. bytes, err := json.Marshal(m)
  28. if err != nil {
  29. return ""
  30. }
  31. return string(bytes)
  32. }
  33. func StrToMap(str string) (map[string]interface{}, error) {
  34. m := make(map[string]interface{})
  35. err := Unmarshal([]byte(str), &m)
  36. if err != nil {
  37. return nil, err
  38. }
  39. return m, nil
  40. }
  41. func StrToJsonArray(str string) ([]interface{}, error) {
  42. var js []interface{}
  43. err := json.Unmarshal([]byte(str), &js)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return js, nil
  48. }
  49. func IsJsonArray(str string) bool {
  50. var js []interface{}
  51. return json.Unmarshal([]byte(str), &js) == nil
  52. }
  53. func IsJsonObject(str string) bool {
  54. var js map[string]interface{}
  55. return json.Unmarshal([]byte(str), &js) == nil
  56. }
  57. func String2Int(str string) int {
  58. num, err := strconv.Atoi(str)
  59. if err != nil {
  60. return 0
  61. }
  62. return num
  63. }
  64. func StringsContains(strs []string, str string) bool {
  65. for _, s := range strs {
  66. if s == str {
  67. return true
  68. }
  69. }
  70. return false
  71. }
  72. // StringToByteSlice []byte only read, panic on append
  73. func StringToByteSlice(s string) []byte {
  74. tmp1 := (*[2]uintptr)(unsafe.Pointer(&s))
  75. tmp2 := [3]uintptr{tmp1[0], tmp1[1], tmp1[1]}
  76. return *(*[]byte)(unsafe.Pointer(&tmp2))
  77. }
  78. func EncodeBase64(str string) string {
  79. return base64.StdEncoding.EncodeToString([]byte(str))
  80. }
  81. func GetJsonString(data any) string {
  82. if data == nil {
  83. return ""
  84. }
  85. b, _ := json.Marshal(data)
  86. return string(b)
  87. }
  88. // MaskSensitiveInfo masks sensitive information like URLs, IPs in a string
  89. // Example:
  90. // http://example.com -> http://***.com
  91. // https://api.test.org/v1/users/123?key=secret -> https://***.org/***/***/?key=***
  92. // https://sub.domain.co.uk/path/to/resource -> https://***.co.uk/***/***
  93. // 192.168.1.1 -> ***.***.***.***
  94. func MaskSensitiveInfo(str string) string {
  95. // Mask URLs
  96. urlPattern := regexp.MustCompile(`(http|https)://[^\s/$.?#].[^\s]*`)
  97. str = urlPattern.ReplaceAllStringFunc(str, func(urlStr string) string {
  98. u, err := url.Parse(urlStr)
  99. if err != nil {
  100. return urlStr
  101. }
  102. host := u.Host
  103. if host == "" {
  104. return urlStr
  105. }
  106. // Split host by dots
  107. parts := strings.Split(host, ".")
  108. if len(parts) < 2 {
  109. // If less than 2 parts, just mask the whole host
  110. return u.Scheme + "://***" + u.Path
  111. }
  112. // Keep the TLD (Top Level Domain) and mask the rest
  113. var maskedHost string
  114. if len(parts) == 2 {
  115. // example.com -> ***.com
  116. maskedHost = "***." + parts[len(parts)-1]
  117. } else {
  118. // Handle cases like sub.domain.co.uk or api.example.com
  119. // Keep last 2 parts if they look like country code TLD (co.uk, com.cn, etc.)
  120. lastPart := parts[len(parts)-1]
  121. secondLastPart := parts[len(parts)-2]
  122. if len(lastPart) == 2 && len(secondLastPart) <= 3 {
  123. // Likely country code TLD like co.uk, com.cn
  124. maskedHost = "***." + secondLastPart + "." + lastPart
  125. } else {
  126. // Regular TLD like .com, .org
  127. maskedHost = "***." + lastPart
  128. }
  129. }
  130. result := u.Scheme + "://" + maskedHost
  131. // Mask path
  132. if u.Path != "" && u.Path != "/" {
  133. pathParts := strings.Split(strings.Trim(u.Path, "/"), "/")
  134. maskedPathParts := make([]string, len(pathParts))
  135. for i := range pathParts {
  136. if pathParts[i] != "" {
  137. maskedPathParts[i] = "***"
  138. }
  139. }
  140. if len(maskedPathParts) > 0 {
  141. result += "/" + strings.Join(maskedPathParts, "/")
  142. }
  143. } else if u.Path == "/" {
  144. result += "/"
  145. }
  146. // Mask query parameters
  147. if u.RawQuery != "" {
  148. values, err := url.ParseQuery(u.RawQuery)
  149. if err != nil {
  150. // If can't parse query, just mask the whole query string
  151. result += "?***"
  152. } else {
  153. maskedParams := make([]string, 0, len(values))
  154. for key := range values {
  155. maskedParams = append(maskedParams, key+"=***")
  156. }
  157. if len(maskedParams) > 0 {
  158. result += "?" + strings.Join(maskedParams, "&")
  159. }
  160. }
  161. }
  162. return result
  163. })
  164. // Mask IP addresses
  165. ipPattern := regexp.MustCompile(`\b(?:\d{1,3}\.){3}\d{1,3}\b`)
  166. str = ipPattern.ReplaceAllString(str, "***.***.***.***")
  167. return str
  168. }