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 }