(feat):增加Base36编解码功能,待测。
This commit is contained in:
108
serialize/base36/base36.go
Normal file
108
serialize/base36/base36.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package base36
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Encode 将字节数据编码为Base36字符串(大写),使用=作为padding字符
|
||||||
|
func Encode(src []byte) string {
|
||||||
|
if len(src) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将字节转换为big.Int
|
||||||
|
num := new(big.Int).SetBytes(src)
|
||||||
|
|
||||||
|
// 如果输入为全零字节,则直接返回"0"
|
||||||
|
if num.Cmp(big.NewInt(0)) == 0 {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进行Base36编码
|
||||||
|
var result strings.Builder
|
||||||
|
base := big.NewInt(36)
|
||||||
|
zero := big.NewInt(0)
|
||||||
|
remainder := new(big.Int)
|
||||||
|
|
||||||
|
// 重复除以36,获取余数作为字符
|
||||||
|
for num.Cmp(zero) > 0 {
|
||||||
|
num.DivMod(num, base, remainder)
|
||||||
|
digit := remainder.Int64()
|
||||||
|
|
||||||
|
if digit < 10 {
|
||||||
|
result.WriteString(fmt.Sprintf("%d", digit))
|
||||||
|
} else {
|
||||||
|
result.WriteString(fmt.Sprintf("%c", 'A'+digit-10))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 反转字符串,因为我们是从低位开始计算的
|
||||||
|
encoded := result.String()
|
||||||
|
runes := []rune(encoded)
|
||||||
|
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
runes[i], runes[j] = runes[j], runes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(runes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 将Base36字符串(可为任意大小写)解码为字节数组
|
||||||
|
func Decode(src string) ([]byte, error) {
|
||||||
|
if src == "" {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除padding字符
|
||||||
|
src = strings.ReplaceAll(src, "=", "")
|
||||||
|
src = strings.ToUpper(src)
|
||||||
|
|
||||||
|
// 使用big.Int进行解码
|
||||||
|
num := big.NewInt(0)
|
||||||
|
base := big.NewInt(36)
|
||||||
|
|
||||||
|
for _, char := range src {
|
||||||
|
var digit int64
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case char >= '0' && char <= '9':
|
||||||
|
digit = int64(char - '0')
|
||||||
|
case char >= 'A' && char <= 'Z':
|
||||||
|
digit = int64(char - 'A' + 10)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid character %c in base36 string", char)
|
||||||
|
}
|
||||||
|
|
||||||
|
num.Mul(num, base)
|
||||||
|
num.Add(num, big.NewInt(digit))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为字节数组
|
||||||
|
return num.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeToString 是Encode的别名,用于保持与标准库一致的命名
|
||||||
|
func EncodeToString(src []byte) string {
|
||||||
|
return Encode(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeString 是Decode的别名,用于保持与标准库一致的命名
|
||||||
|
func DecodeString(src string) ([]byte, error) {
|
||||||
|
return Decode(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeInt64 将int64转换为Base36字符串
|
||||||
|
func EncodeInt64(num int64) string {
|
||||||
|
return EncodeToString(big.NewInt(num).Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeToInt64 将Base36字符串解码为int64
|
||||||
|
func DecodeToInt64(src string) (int64, error) {
|
||||||
|
bytes, err := DecodeString(src)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return new(big.Int).SetBytes(bytes).Int64(), nil
|
||||||
|
}
|
Reference in New Issue
Block a user