go/idgen/idgen.go

54 lines
923 B
Go
Raw Permalink Normal View History

2024-11-11 05:36:55 +00:00
package idgen
import (
"crypto/rand"
"encoding/base32"
"sync"
"time"
)
// Creates a new, random token.
func NewToken() string {
buf := make([]byte, 20)
_, err := rand.Read(buf)
if err != nil {
panic(err)
}
return base32.StdEncoding.EncodeToString(buf)
}
var (
lock sync.Mutex
ts int64 = time.Now().Unix()
counter int64 = 1
counterMax int64 = 1 << 20
)
// NextID can generate ~1M ints per second for a given nodeID.
//
// nodeID must be less than 64.
func NextID(nodeID int64) int64 {
lock.Lock()
defer lock.Unlock()
tt := time.Now().Unix()
if tt > ts {
ts = tt
counter = 1
} else {
counter++
if counter == counterMax {
panic("Too many IDs.")
}
}
return (ts << 26) + (nodeID << 20) + counter
}
func SplitID(id int64) (unixTime, nodeID, counter int64) {
counter = id & (0x00000000000FFFFF)
nodeID = (id >> 20) & (0x000000000000003F)
unixTime = id >> 26
return
}