Golang中如何缩短UUID字符串
Golang中如何缩短UUID字符串 大家好! 我正在寻找一种替代方案,以使 UUID.String() 的字符串表示更短。
当前长度是36个字符,例如:964238a0-8188-465f-8347-657819bf789a。 使用 ascii85 编码后长度为20,例如:Q9mR(JVZd&K1BKt)8CEb
有什么想法吗?
package main
import (
"encoding/ascii85"
"fmt"
"github.com/google/uuid"
)
func main() {
originalUUID := uuid.New()
originalSlice, _ := originalUUID.MarshalBinary()
enc := make([]byte, ascii85.MaxEncodedLen(len(originalUUID)))
ascii85.Encode(enc, originalSlice)
newStringID := originalUUID.String()
fmt.Printf("uuid - len: %d, string: '%s'\n", len(newStringID), newStringID)
fmt.Printf("ascii85 - len: %d, string: '%s'\n", len(enc), string(enc))
// Just for testing:
dst := make([]byte, 16)
ascii85.Decode(dst, enc, true)
uuidDecoded, _ := uuid.FromBytes(dst)
fmt.Printf("decoded - len: %d, string: '%s'\n", len(uuidDecoded.String()), uuidDecoded.String())
}
输出:
uuid - len: 36, string: ‘964238a0-8188-465f-8347-657819bf789a’ ascii85 - len: 20, string: ‘Q9mR(JVZd&K1BKt)8CEb’ decoded - len: 36, string: ‘964238a0-8188-465f-8347-657819bf789a’
更多关于Golang中如何缩短UUID字符串的实战教程也可以访问 https://www.itying.com/category-94-b0.html
为了你自己好,请以规范化的表示形式发送给他们。
从长远来看,这会为你省去很多麻烦。
为什么不直接将其存储为 BLOB/BINARY/BYTEA 或您的数据库管理系统用于存储二进制数据的任何数据类型呢?为什么要在数据库中将其转换为字符串?
你好 @GonzaSaya,
我虽然不是UUID专家,但在我看来,ascii85已经是一种非常紧凑的格式了,因为它使用了大量字符进行编码。
要获得更短的ID,我会尝试以下方法之一:
-
使用二进制压缩。如果ID不需要是可打印的,这种方法很合适。
-
使用另一种唯一ID格式。UUID旨在实现全局唯一性。也就是说,在世界任何地方生成相同UUID的可能性应该非常低。如果你可以接受一个仅在数据库、服务器集群或公司内部等范围内唯一的ID,那么除了UUID之外,还有其他算法可以生成更短的唯一ID。
可以使用Base32或Base64编码来进一步缩短UUID的字符串表示。以下是几种实现方案:
1. Base64编码(22字符)
package main
import (
"encoding/base64"
"fmt"
"github.com/google/uuid"
)
func main() {
id := uuid.New()
// 标准Base64
b64 := base64.RawURLEncoding.EncodeToString(id[:])
fmt.Printf("Base64 - len: %d, string: '%s'\n", len(b64), b64)
// 解码验证
decoded, _ := base64.RawURLEncoding.DecodeString(b64)
uuidDecoded, _ := uuid.FromBytes(decoded)
fmt.Printf("Decoded: %s\n", uuidDecoded)
}
2. Base32编码(26字符)
package main
import (
"encoding/base32"
"fmt"
"github.com/google/uuid"
"strings"
)
func main() {
id := uuid.New()
// Base32编码(去掉填充字符)
b32 := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(id[:])
fmt.Printf("Base32 - len: %d, string: '%s'\n", len(b32), b32)
// 解码验证
decoded, _ := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(b32)
uuidDecoded, _ := uuid.FromBytes(decoded)
fmt.Printf("Decoded: %s\n", uuidDecoded)
}
3. Base58编码(约22字符)
package main
import (
"fmt"
"github.com/google/uuid"
"github.com/btcsuite/btcutil/base58"
)
func main() {
id := uuid.New()
// Base58编码(比特币风格)
b58 := base58.Encode(id[:])
fmt.Printf("Base58 - len: %d, string: '%s'\n", len(b58), b58)
// 解码验证
decoded := base58.Decode(b58)
uuidDecoded, _ := uuid.FromBytes(decoded)
fmt.Printf("Decoded: %s\n", uuidDecoded)
}
4. 十六进制压缩(32字符)
package main
import (
"fmt"
"github.com/google/uuid"
"strings"
)
func main() {
id := uuid.New()
// 去掉连字符的十六进制
hexStr := strings.ReplaceAll(id.String(), "-", "")
fmt.Printf("Hex - len: %d, string: '%s'\n", len(hexStr), hexStr)
// 解码验证
uuidDecoded, _ := uuid.Parse(hexStr)
fmt.Printf("Decoded: %s\n", uuidDecoded)
}
5. 自定义Base62编码(约22字符)
package main
import (
"fmt"
"github.com/google/uuid"
"math/big"
)
const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
func encodeBase62(data []byte) string {
n := new(big.Int).SetBytes(data)
result := ""
zero := big.NewInt(0)
base := big.NewInt(62)
for n.Cmp(zero) > 0 {
mod := new(big.Int)
n.DivMod(n, base, mod)
result = string(base62Chars[mod.Int64()]) + result
}
return result
}
func main() {
id := uuid.New()
base62 := encodeBase62(id[:])
fmt.Printf("Base62 - len: %d, string: '%s'\n", len(base62), base62)
}
性能对比示例
package main
import (
"encoding/base32"
"encoding/base64"
"fmt"
"github.com/google/uuid"
"strings"
"time"
)
func main() {
id := uuid.New()
// 各种编码方式
methods := []struct {
name string
fn func(uuid.UUID) string
}{
{"Original", func(u uuid.UUID) string { return u.String() }},
{"Hex", func(u uuid.UUID) string { return strings.ReplaceAll(u.String(), "-", "") }},
{"Base64", func(u uuid.UUID) string {
return base64.RawURLEncoding.EncodeToString(u[:])
}},
{"Base32", func(u uuid.UUID) string {
return base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(u[:])
}},
}
for _, method := range methods {
start := time.Now()
encoded := method.fn(id)
elapsed := time.Since(start)
fmt.Printf("%-10s len: %2d, time: %v\n",
method.name+":", len(encoded), elapsed)
}
}
输出示例:
Original: len: 36, time: 1.042µs
Hex: len: 32, time: 1.125µs
Base64: len: 22, time: 1.292µs
Base32: len: 26, time: 1.375µs
Base64.RawURLEncoding是最佳选择,它生成22个字符的URL安全字符串,没有填充字符,且Go标准库原生支持。

