str.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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, and domain names 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. // openai.com -> ***.com
  95. // www.openai.com -> ***.***.com
  96. // api.openai.com -> ***.***.com
  97. func MaskSensitiveInfo(str string) string {
  98. // Mask URLs
  99. urlPattern := regexp.MustCompile(`(http|https)://[^\s/$.?#].[^\s]*`)
  100. str = urlPattern.ReplaceAllStringFunc(str, func(urlStr string) string {
  101. u, err := url.Parse(urlStr)
  102. if err != nil {
  103. return urlStr
  104. }
  105. host := u.Host
  106. if host == "" {
  107. return urlStr
  108. }
  109. // Split host by dots
  110. parts := strings.Split(host, ".")
  111. if len(parts) < 2 {
  112. // If less than 2 parts, just mask the whole host
  113. return u.Scheme + "://***" + u.Path
  114. }
  115. // Keep the TLD (Top Level Domain) and mask the rest
  116. var maskedHost string
  117. if len(parts) == 2 {
  118. // example.com -> ***.com
  119. maskedHost = "***." + parts[len(parts)-1]
  120. } else {
  121. // Handle cases like sub.domain.co.uk or api.example.com
  122. // Keep last 2 parts if they look like country code TLD (co.uk, com.cn, etc.)
  123. lastPart := parts[len(parts)-1]
  124. secondLastPart := parts[len(parts)-2]
  125. if len(lastPart) == 2 && len(secondLastPart) <= 3 {
  126. // Likely country code TLD like co.uk, com.cn
  127. maskedHost = "***." + secondLastPart + "." + lastPart
  128. } else {
  129. // Regular TLD like .com, .org
  130. maskedHost = "***." + lastPart
  131. }
  132. }
  133. result := u.Scheme + "://" + maskedHost
  134. // Mask path
  135. if u.Path != "" && u.Path != "/" {
  136. pathParts := strings.Split(strings.Trim(u.Path, "/"), "/")
  137. maskedPathParts := make([]string, len(pathParts))
  138. for i := range pathParts {
  139. if pathParts[i] != "" {
  140. maskedPathParts[i] = "***"
  141. }
  142. }
  143. if len(maskedPathParts) > 0 {
  144. result += "/" + strings.Join(maskedPathParts, "/")
  145. }
  146. } else if u.Path == "/" {
  147. result += "/"
  148. }
  149. // Mask query parameters
  150. if u.RawQuery != "" {
  151. values, err := url.ParseQuery(u.RawQuery)
  152. if err != nil {
  153. // If can't parse query, just mask the whole query string
  154. result += "?***"
  155. } else {
  156. maskedParams := make([]string, 0, len(values))
  157. for key := range values {
  158. maskedParams = append(maskedParams, key+"=***")
  159. }
  160. if len(maskedParams) > 0 {
  161. result += "?" + strings.Join(maskedParams, "&")
  162. }
  163. }
  164. }
  165. return result
  166. })
  167. // Mask domain names without protocol (like openai.com, www.openai.com)
  168. domainPattern := regexp.MustCompile(`\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}\b`)
  169. str = domainPattern.ReplaceAllStringFunc(str, func(domain string) string {
  170. // Skip if it's already been processed as part of a URL
  171. if strings.Contains(str, "://"+domain) {
  172. return domain
  173. }
  174. parts := strings.Split(domain, ".")
  175. if len(parts) < 2 {
  176. return domain
  177. }
  178. // Handle different domain patterns
  179. if len(parts) == 2 {
  180. // openai.com -> ***.com
  181. return "***." + parts[1]
  182. } else {
  183. // www.openai.com -> ***.***.com
  184. // api.openai.com -> ***.***.com
  185. lastPart := parts[len(parts)-1]
  186. return "***.***." + lastPart
  187. }
  188. })
  189. // Mask IP addresses
  190. ipPattern := regexp.MustCompile(`\b(?:\d{1,3}\.){3}\d{1,3}\b`)
  191. str = ipPattern.ReplaceAllString(str, "***.***.***.***")
  192. return str
  193. }