package utils import ( "errors" "strconv" "sync" "time" ) // Snowflake is a uint32-sized ID with 32 node support and 8.5 year lifespan type Snowflake uint32 // ID is an alias for Snowflake type ID = Snowflake func (s Snowflake) String() string { return strconv.FormatUint(uint64(s), 16) } // ParseSnowflake parses a string into a snowflake, if possible func ParseSnowflake(s string) (Snowflake, error) { i, err := strconv.ParseUint(s, 16, 32) if err != nil { return 0, err } return Snowflake(i), nil } // DefaultGenerator is a Generator with the epoch set to Jan 1, 2025 UTC // Generator holds info needed for generating snowflakes with 32 node support type Generator struct { Epoch time.Time nodeID uint8 // 0-31 (5位,支持32个节点) sequence uint8 // 0-255 (8位,支持每秒256个ID) lastSec uint32 // 上次生成ID的秒级时间戳 mu sync.Mutex } // NewGen returns a new generator with specified epoch and node ID func NewGen(epoch time.Time, nodeID uint8) *Generator { if nodeID >= 32 { // 5位最多支持0-31 panic(errors.New("node ID must be between 0 and 31")) } return &Generator{ Epoch: epoch, nodeID: nodeID, } } // Get generates a new unique snowflake ID and returns it as uint32 func (g *Generator) Get() uint32 { g.mu.Lock() defer g.mu.Unlock() // 获取当前时间戳(自纪元以来的秒数) now := time.Now() sec := uint32(now.Sub(g.Epoch).Seconds()) // 检查时间戳是否超出28位限制 (2^28 - 1 = 268435455秒 ≈ 8.5年) if sec >= (1 << 28) { panic(errors.New("timestamp overflow: please update epoch")) } // 处理时间回拨 if sec < g.lastSec { // 计算需要等待的时间 sleepDuration := time.Duration(g.lastSec-sec) * time.Second // 添加1毫秒缓冲,确保时间确实已过 sleepDuration += time.Millisecond // 等待时间追上 time.Sleep(sleepDuration) // 重新获取时间戳 now = time.Now() sec = uint32(now.Sub(g.Epoch).Seconds()) // 再次检查,防止极端情况 if sec < g.lastSec { panic(errors.New("clock moved backwards beyond recovery")) } } // 处理同一秒内的序列号 if sec == g.lastSec { g.sequence++ // 序列号溢出(8位最大255) if g.sequence > 255 { // 0-255是有效范围 // 等待到下一秒 sleepDuration := time.Second - time.Duration(now.Nanosecond())*time.Nanosecond + time.Microsecond time.Sleep(sleepDuration) now = time.Now() sec = uint32(now.Sub(g.Epoch).Seconds()) g.sequence = 0 } } else { // 新的一秒,重置序列号 g.sequence = 0 } // 更新上次时间戳 g.lastSec = sec // 组装ID (32位): // [28位秒级时间戳][5位节点ID][8位序列号] var id uint32 id |= (sec << 13) // 左移13位(5+8)放置秒级时间戳 id |= (uint32(g.nodeID) << 8) // 左移8位放置节点ID id |= uint32(g.sequence) // 放置序列号 return id } // Parse extracts timestamp, node ID and sequence from a snowflake func (g *Generator) Parse(id uint32) (t time.Time, nodeID uint8, sequence uint8) { // 提取各部分信息 sec := id >> 13 nodeID = uint8((id >> 8) & 0x1F) // 5位掩码(0x1F = 31) sequence = uint8(id & 0xFF) // 8位掩码(0xFF = 255) // 计算实际时间 totalNanos := g.Epoch.UnixNano() + int64(sec)*int64(time.Second) t = time.Unix(0, totalNanos).UTC() return } // GetNodeID returns the current node ID func (g *Generator) GetNodeID() uint8 { return g.nodeID } // GetLastTimestamp returns the last timestamp used (for testing/debugging) func (g *Generator) GetLastTimestamp() uint32 { g.mu.Lock() defer g.mu.Unlock() return g.lastSec } // MaxAge returns the maximum age (in seconds) that this generator can handle before overflow func (g *Generator) MaxAge() uint32 { return (1 << 28) - 1 // 268435455秒,约8.5年 } // MaxSequencePerSecond returns the maximum number of sequences per second func (g *Generator) MaxSequencePerSecond() uint8 { return 255 // 2^8 - 1 }