|
|
package common |
|
|
|
|
|
import ( |
|
|
"encoding/base64" |
|
|
"encoding/json" |
|
|
"math/rand" |
|
|
"net/url" |
|
|
"regexp" |
|
|
"strconv" |
|
|
"strings" |
|
|
"unsafe" |
|
|
) |
|
|
|
|
|
func GetStringIfEmpty(str string, defaultValue string) string { |
|
|
if str == "" { |
|
|
return defaultValue |
|
|
} |
|
|
return str |
|
|
} |
|
|
|
|
|
func GetRandomString(length int) string { |
|
|
|
|
|
key := make([]byte, length) |
|
|
for i := 0; i < length; i++ { |
|
|
key[i] = keyChars[rand.Intn(len(keyChars))] |
|
|
} |
|
|
return string(key) |
|
|
} |
|
|
|
|
|
func MapToJsonStr(m map[string]interface{}) string { |
|
|
bytes, err := json.Marshal(m) |
|
|
if err != nil { |
|
|
return "" |
|
|
} |
|
|
return string(bytes) |
|
|
} |
|
|
|
|
|
func StrToMap(str string) (map[string]interface{}, error) { |
|
|
m := make(map[string]interface{}) |
|
|
err := Unmarshal([]byte(str), &m) |
|
|
if err != nil { |
|
|
return nil, err |
|
|
} |
|
|
return m, nil |
|
|
} |
|
|
|
|
|
func StrToJsonArray(str string) ([]interface{}, error) { |
|
|
var js []interface{} |
|
|
err := json.Unmarshal([]byte(str), &js) |
|
|
if err != nil { |
|
|
return nil, err |
|
|
} |
|
|
return js, nil |
|
|
} |
|
|
|
|
|
func IsJsonArray(str string) bool { |
|
|
var js []interface{} |
|
|
return json.Unmarshal([]byte(str), &js) == nil |
|
|
} |
|
|
|
|
|
func IsJsonObject(str string) bool { |
|
|
var js map[string]interface{} |
|
|
return json.Unmarshal([]byte(str), &js) == nil |
|
|
} |
|
|
|
|
|
func String2Int(str string) int { |
|
|
num, err := strconv.Atoi(str) |
|
|
if err != nil { |
|
|
return 0 |
|
|
} |
|
|
return num |
|
|
} |
|
|
|
|
|
func StringsContains(strs []string, str string) bool { |
|
|
for _, s := range strs { |
|
|
if s == str { |
|
|
return true |
|
|
} |
|
|
} |
|
|
return false |
|
|
} |
|
|
|
|
|
|
|
|
func StringToByteSlice(s string) []byte { |
|
|
tmp1 := (*[2]uintptr)(unsafe.Pointer(&s)) |
|
|
tmp2 := [3]uintptr{tmp1[0], tmp1[1], tmp1[1]} |
|
|
return *(*[]byte)(unsafe.Pointer(&tmp2)) |
|
|
} |
|
|
|
|
|
func EncodeBase64(str string) string { |
|
|
return base64.StdEncoding.EncodeToString([]byte(str)) |
|
|
} |
|
|
|
|
|
func GetJsonString(data any) string { |
|
|
if data == nil { |
|
|
return "" |
|
|
} |
|
|
b, _ := json.Marshal(data) |
|
|
return string(b) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func MaskEmail(email string) string { |
|
|
if email == "" { |
|
|
return "***masked***" |
|
|
} |
|
|
|
|
|
|
|
|
atIndex := strings.Index(email, "@") |
|
|
if atIndex == -1 { |
|
|
|
|
|
return "***masked***" |
|
|
} |
|
|
|
|
|
|
|
|
return "***@" + email[atIndex+1:] |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func maskHostTail(parts []string) []string { |
|
|
if len(parts) < 2 { |
|
|
return parts |
|
|
} |
|
|
lastPart := parts[len(parts)-1] |
|
|
secondLastPart := parts[len(parts)-2] |
|
|
if len(lastPart) == 2 && len(secondLastPart) <= 3 { |
|
|
|
|
|
return []string{secondLastPart, lastPart} |
|
|
} |
|
|
return []string{lastPart} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func maskHostForURL(host string) string { |
|
|
parts := strings.Split(host, ".") |
|
|
if len(parts) < 2 { |
|
|
return "***" |
|
|
} |
|
|
tail := maskHostTail(parts) |
|
|
return "***." + strings.Join(tail, ".") |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func maskHostForPlainDomain(domain string) string { |
|
|
parts := strings.Split(domain, ".") |
|
|
if len(parts) < 2 { |
|
|
return domain |
|
|
} |
|
|
tail := maskHostTail(parts) |
|
|
numStars := len(parts) - len(tail) |
|
|
if numStars < 1 { |
|
|
numStars = 1 |
|
|
} |
|
|
stars := strings.TrimSuffix(strings.Repeat("***.", numStars), ".") |
|
|
return stars + "." + strings.Join(tail, ".") |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func MaskSensitiveInfo(str string) string { |
|
|
|
|
|
urlPattern := regexp.MustCompile(`(http|https)://[^\s/$.?#].[^\s]*`) |
|
|
str = urlPattern.ReplaceAllStringFunc(str, func(urlStr string) string { |
|
|
u, err := url.Parse(urlStr) |
|
|
if err != nil { |
|
|
return urlStr |
|
|
} |
|
|
|
|
|
host := u.Host |
|
|
if host == "" { |
|
|
return urlStr |
|
|
} |
|
|
|
|
|
|
|
|
maskedHost := maskHostForURL(host) |
|
|
|
|
|
result := u.Scheme + "://" + maskedHost |
|
|
|
|
|
|
|
|
if u.Path != "" && u.Path != "/" { |
|
|
pathParts := strings.Split(strings.Trim(u.Path, "/"), "/") |
|
|
maskedPathParts := make([]string, len(pathParts)) |
|
|
for i := range pathParts { |
|
|
if pathParts[i] != "" { |
|
|
maskedPathParts[i] = "***" |
|
|
} |
|
|
} |
|
|
if len(maskedPathParts) > 0 { |
|
|
result += "/" + strings.Join(maskedPathParts, "/") |
|
|
} |
|
|
} else if u.Path == "/" { |
|
|
result += "/" |
|
|
} |
|
|
|
|
|
|
|
|
if u.RawQuery != "" { |
|
|
values, err := url.ParseQuery(u.RawQuery) |
|
|
if err != nil { |
|
|
|
|
|
result += "?***" |
|
|
} else { |
|
|
maskedParams := make([]string, 0, len(values)) |
|
|
for key := range values { |
|
|
maskedParams = append(maskedParams, key+"=***") |
|
|
} |
|
|
if len(maskedParams) > 0 { |
|
|
result += "?" + strings.Join(maskedParams, "&") |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
return result |
|
|
}) |
|
|
|
|
|
|
|
|
domainPattern := regexp.MustCompile(`\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}\b`) |
|
|
str = domainPattern.ReplaceAllStringFunc(str, func(domain string) string { |
|
|
return maskHostForPlainDomain(domain) |
|
|
}) |
|
|
|
|
|
|
|
|
ipPattern := regexp.MustCompile(`\b(?:\d{1,3}\.){3}\d{1,3}\b`) |
|
|
str = ipPattern.ReplaceAllString(str, "***.***.***.***") |
|
|
|
|
|
return str |
|
|
} |
|
|
|