135 lines
3.2 KiB
Go
135 lines
3.2 KiB
Go
package encoding
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"html"
|
|
"net/url"
|
|
"sort"
|
|
"strings"
|
|
"unicode/utf8"
|
|
|
|
"apigo.cc/go/cast"
|
|
)
|
|
|
|
// Hex 将数据转换为 Hex 编码的字符串
|
|
func Hex(data any) string {
|
|
b := cast.To[[]byte](data)
|
|
return hex.EncodeToString(b)
|
|
}
|
|
|
|
// UnHex 将 Hex 编码的数据解码为字节切片
|
|
func UnHex(data any) ([]byte, error) {
|
|
s := cast.String(data)
|
|
return hex.DecodeString(s)
|
|
}
|
|
|
|
// Base64 将数据转换为 Base64 编码的字符串
|
|
func Base64(data any) string {
|
|
b := cast.To[[]byte](data)
|
|
return base64.StdEncoding.EncodeToString(b)
|
|
}
|
|
|
|
// UnBase64 将 Base64 编码的数据解码为字节切片(自动兼容有无填充)
|
|
func UnBase64(data any) ([]byte, error) {
|
|
s := cast.String(data)
|
|
if len(s) > 0 && s[len(s)-1] == '=' {
|
|
return base64.StdEncoding.DecodeString(s)
|
|
}
|
|
return base64.RawStdEncoding.DecodeString(s)
|
|
}
|
|
|
|
// Base64Raw 将数据转换为无填充的 Base64 编码的字符串
|
|
func Base64Raw(data any) string {
|
|
b := cast.To[[]byte](data)
|
|
return base64.RawStdEncoding.EncodeToString(b)
|
|
}
|
|
|
|
// URLBase64 将数据转换为 URL 安全的 Base64 编码的字符串
|
|
func URLBase64(data any) string {
|
|
b := cast.To[[]byte](data)
|
|
return base64.URLEncoding.EncodeToString(b)
|
|
}
|
|
|
|
// UnURLBase64 将 URL 安全的 Base64 编码的数据解码为字节切片(自动兼容有无填充)
|
|
func UnURLBase64(data any) ([]byte, error) {
|
|
s := cast.String(data)
|
|
if len(s) > 0 && s[len(s)-1] == '=' {
|
|
return base64.URLEncoding.DecodeString(s)
|
|
}
|
|
return base64.RawURLEncoding.DecodeString(s)
|
|
}
|
|
|
|
// URLBase64Raw 将数据转换为 URL 安全且无填充的 Base64 编码的字符串
|
|
func URLBase64Raw(data any) string {
|
|
b := cast.To[[]byte](data)
|
|
return base64.RawURLEncoding.EncodeToString(b)
|
|
}
|
|
|
|
// URLEncode 对数据进行 URL 编码
|
|
func URLEncode(data any) string {
|
|
return url.QueryEscape(cast.String(data))
|
|
}
|
|
|
|
// UnURLEncode 对字符串进行 URL 解码
|
|
func UnURLEncode(data any) ([]byte, error) {
|
|
res, err := url.QueryUnescape(cast.String(data))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []byte(res), nil
|
|
}
|
|
|
|
// HTMLEscape 对数据进行 HTML 转义
|
|
func HTMLEscape(data any) string {
|
|
return html.EscapeString(cast.String(data))
|
|
}
|
|
|
|
// HTMLUnescape 对 HTML 字符串进行反转义
|
|
func HTMLUnescape(data any) string {
|
|
return html.UnescapeString(cast.String(data))
|
|
}
|
|
|
|
// UTF8Valid 检查数据是否为有效的 UTF-8 编码
|
|
func UTF8Valid(data any) bool {
|
|
return utf8.Valid(cast.To[[]byte](data))
|
|
}
|
|
|
|
// SortJoin 将 Map 或 Struct 转换为排序并拼接后的字符串 (常用于签名)
|
|
func SortJoin(v any, separator, connector string, urlEncode bool) string {
|
|
var m map[string]any
|
|
if vm, ok := v.(map[string]any); ok {
|
|
m = vm
|
|
} else if v != nil {
|
|
cast.Convert(&m, v)
|
|
}
|
|
|
|
if len(m) == 0 {
|
|
return ""
|
|
}
|
|
|
|
keys := make([]string, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
var builder strings.Builder
|
|
for i, k := range keys {
|
|
if i > 0 {
|
|
builder.WriteString(separator)
|
|
}
|
|
val := cast.String(m[k])
|
|
if urlEncode {
|
|
builder.WriteString(url.QueryEscape(k))
|
|
builder.WriteString(connector)
|
|
builder.WriteString(url.QueryEscape(val))
|
|
} else {
|
|
builder.WriteString(k)
|
|
builder.WriteString(connector)
|
|
builder.WriteString(val)
|
|
}
|
|
}
|
|
return builder.String()
|
|
}
|