| 12345678910111213141516171819202122232425262728293031323334 |
- package alert
- import (
- "crypto/rand"
- "encoding/hex"
- "sync/atomic"
- "time"
- )
- // ulidLike returns a 26-char time-sortable ID. Layout:
- // - first 10 hex chars: unix ms (fits in 40 bits, padded)
- // - next 16 hex chars: random
- // Not a real ULID, but good enough for log ordering and broker keys.
- func ulidLike() string {
- now := time.Now().UTC().UnixMilli()
- var msBuf [8]byte
- for i := 7; i >= 0; i-- {
- msBuf[i] = byte(now)
- now >>= 8
- }
- var rnd [8]byte
- if _, err := rand.Read(rnd[:]); err != nil {
- // crypto/rand should never fail; if it does, fall back to atomic counter
- // so we still produce a unique ID.
- fb := atomic.AddUint64(&fallbackCounter, 1)
- for i := 7; i >= 0; i-- {
- rnd[i] = byte(fb)
- fb >>= 8
- }
- }
- return hex.EncodeToString(msBuf[:])[:10] + hex.EncodeToString(rnd[:])
- }
- var fallbackCounter uint64
|