55 lines
1.2 KiB
Go
55 lines
1.2 KiB
Go
package entity
|
|
|
|
import (
|
|
"regexp"
|
|
)
|
|
|
|
const (
|
|
SparkIDMin = 8
|
|
SparkIDMax = 16
|
|
// sparkIDBodyLen is 13: int64 fits in 13 base36 digits (36^13 > 2^63).
|
|
sparkIDBodyLen = 13
|
|
sparkIDPrefix = 's'
|
|
)
|
|
|
|
var sparkIDRe = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_]{7,15}$`)
|
|
|
|
// ValidSparkID checks a new or updated handle. Existing rows may still be 6-32.
|
|
func ValidSparkID(id string) bool {
|
|
n := len(id)
|
|
return n >= SparkIDMin && n <= SparkIDMax && sparkIDRe.MatchString(id)
|
|
}
|
|
|
|
// DefaultSparkID maps a Snowflake uid to a unique 14-character handle.
|
|
// Format: 's' + 13-digit zero-padded base36(uid). Same uid always yields the same id;
|
|
// different uids never collide because the body is a fixed-width encoding of the integer.
|
|
func DefaultSparkID(userID int64) string {
|
|
if userID < 0 {
|
|
userID = -userID
|
|
}
|
|
body := strconv36(userID)
|
|
var b [1 + sparkIDBodyLen]byte
|
|
b[0] = sparkIDPrefix
|
|
pad := sparkIDBodyLen - len(body)
|
|
for i := 1; i <= pad; i++ {
|
|
b[i] = '0'
|
|
}
|
|
copy(b[1+pad:], body)
|
|
return string(b[:])
|
|
}
|
|
|
|
func strconv36(n int64) string {
|
|
const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
|
|
if n == 0 {
|
|
return "0"
|
|
}
|
|
var buf [16]byte
|
|
i := len(buf)
|
|
for n > 0 {
|
|
i--
|
|
buf[i] = digits[n%36]
|
|
n /= 36
|
|
}
|
|
return string(buf[i:])
|
|
}
|