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 }