package id
import (
"crypto/md5"
"crypto/rand"
"fmt"
"math/big"
"strings"
)
func NewRandom() string {
var b [16]byte
_, _ = rand.Read(b[:])
return Encode(b)
}
func Encode(b [16]byte) string {
return fmt.Sprintf("%022s", new(big.Int).SetBytes(b[:]).Text(62))
}
func Decode(s string) ([]byte, error) {
if len(s) != 22 {
return nil, fmt.Errorf("invalid id length %d", len(s))
}
v, ok := new(big.Int).SetString(s, 62)
if !ok || v.Sign() < 0 {
return nil, fmt.Errorf("invalid base62 id %q", s)
}
if v.BitLen() > 128 {
return nil, fmt.Errorf("id %q overflows 128 bits", s)
}
return v.FillBytes(make([]byte, 16)), nil
}
func NewHash(data ...string) string {
hash := md5.New()
for _, d := range data {
hash.Write([]byte(d))
hash.Write([]byte(string('\u200b')))
}
return Encode([16]byte(hash.Sum(nil)))
}
func NewTagID(name, value string) string {
return NewHash(strings.ToLower(name), strings.ToLower(value))
}