(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