package goutil import ( "bytes" "compress/gzip" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/json" "encoding/xml" "errors" "io" "unicode" "github.com/speps/go-hashids" ) // EncodeJSON encode anything to json string func EncodeJSON(v interface{}) string { b, _ := json.Marshal(v) return string(b) } // EncodeJSON encode anything to json string func EncodeJSONIndent(v interface{}) string { b, _ := json.MarshalIndent(v, " ", " ") return string(b) } // EncodeJSON encode anything to json string func EncodeXML(v interface{}) string { b, _ := xml.Marshal(v) return string(b) } // EncodeJSON encode anything to json string func EncodeXMLIndent(v interface{}) string { b, _ := xml.MarshalIndent(v, " ", " ") return string(b) } func HasChinese(str string) bool { for _, r := range str { if unicode.Is(unicode.Han, r) { return true } } return false } func EncryptID(data int64, salt string) string { hd := hashids.NewData() hd.Salt = salt h, _ := hashids.NewWithData(hd) e, _ := h.Encode([]int{int(data)}) return e } func DecryptID(data, salt string) int64 { hd := hashids.NewData() hd.Salt = salt h, _ := hashids.NewWithData(hd) e, _ := h.DecodeWithError(data) return int64(e[0]) } // 先压缩再加密(适合长文本) func Encrypt(plaintext string, key string) string { // 1. 压缩 var buf bytes.Buffer gz := gzip.NewWriter(&buf) if _, err := gz.Write([]byte(plaintext)); err != nil { return "" } if err := gz.Close(); err != nil { return "" } compressed := buf.Bytes() // 2. 加密(使用AES-GCM) block, err := aes.NewCipher([]byte(Md5(key))) if err != nil { return "" } gcm, err := cipher.NewGCM(block) if err != nil { return "" } nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return "" } ciphertext := gcm.Seal(nonce, nonce, compressed, nil) // 使用RawURLEncoding return base64.RawURLEncoding.EncodeToString(ciphertext) } func Decrypt(encoded string, key string) (string, error) { data, err := base64.RawURLEncoding.DecodeString(encoded) if err != nil { return "", err } block, err := aes.NewCipher([]byte(Md5(key))) if err != nil { return "", err } gcm, err := cipher.NewGCM(block) if err != nil { return "", err } nonceSize := gcm.NonceSize() if len(data) < nonceSize { return "", errors.New("数据太短") } nonce := data[:nonceSize] ciphertext := data[nonceSize:] compressed, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { return "", err } // 解压缩 reader, err := gzip.NewReader(bytes.NewReader(compressed)) if err != nil { return "", err } defer reader.Close() result, err := io.ReadAll(reader) if err != nil { return "", err } return string(result), nil }