Files
Meshray-Manager/pkg/shortid/encoder.go
T
2026-06-30 15:14:37 +08:00

79 lines
1.9 KiB
Go

package shortid
import (
"bytes"
"encoding/base64"
"encoding/binary"
"errors"
)
// EncodeID 将 uint64 雪花 ID 编码为短字符串(推荐)
// 使用 Base64 URL 安全编码,结果长度约 11 字符
func EncodeID(id uint64) string {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, id)
return base64.RawURLEncoding.EncodeToString(buf)
}
// DecodeID 解码短字符串为 uint64
func DecodeID(s string) (uint64, error) {
data, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return 0, err
}
if len(data) > 8 {
return 0, errors.New("数据过长")
}
// 补齐到 8 字节
buf := make([]byte, 8)
copy(buf[8-len(data):], data)
return binary.BigEndian.Uint64(buf), nil
}
// EncodeIDCompact 紧凑编码(去除前导零,适合小 ID)
func EncodeIDCompact(id uint64) string {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, id)
// 去除前导零
trimmed := bytes.TrimLeft(buf, "\x00")
if len(trimmed) == 0 {
trimmed = []byte{0}
}
return base64.RawURLEncoding.EncodeToString(trimmed)
}
// DecodeIDCompact 解码紧凑编码
func DecodeIDCompact(s string) (uint64, error) {
data, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return 0, err
}
// 还原到 8 字节
buf := make([]byte, 8)
copy(buf[8-len(data):], data)
return binary.BigEndian.Uint64(buf), nil
}
// GenerateMeshSeedPrefix 生成 MeshSeed TXT 记录前缀
// 格式:_meshray.{encoded_id}
func GenerateMeshSeedPrefix(networkID uint64) string {
shortID := EncodeID(networkID)
return "_meshray." + shortID
}
// ExtractNetworkID 从 TXT 记录前缀提取网络 ID
func ExtractNetworkID(prefix string) (uint64, error) {
// 格式:_meshray.{encoded_id}
if len(prefix) <= 9 || prefix[:9] != "_meshray." {
return 0, errors.New("非标准前缀格式")
}
encodedID := prefix[9:] // 提取 _meshray. 后面的部分
return DecodeID(encodedID)
}