/* * 薄雾算法 * * 1 2 48 56 64 * +------+-----------------------------------------------------+----------+----------+ * retain | increas | salt | sequence | * +------+-----------------------------------------------------+----------+----------+ * 0 | 0000000000 0000000000 0000000000 0000000000 0000000 | 00000000 | 00000000 | * +------+-----------------------------------------------------+------------+--------+ * * 0. 最高位,占 1 位,保持为 0,使得值永远为正数; * 1. 自增数,占 47 位,自增数在高位能保证结果值呈递增态势,遂低位可以为所欲为; * 2. 随机因子一,占 8 位,上限数值 255,使结果值不可预测; * 3. 随机因子二,占 8 位,上限数值 255,使结果值不可预测; * * 编号上限为百万亿级,上限值计算为 140737488355327 即 int64(1 << 47 - 1),假设每天取值 10 亿,能使用 385+ 年 */ package main import ( "crypto/rand" "fmt" "math/big" "strconv" "sync" "time" ) const startYear = 2019 const saltBit = uint(8) // 随机因子二进制位数 const saltShift = uint(8) // 随机因子移位数 const increasShift = saltBit + saltShift // 自增数移位数 func NewIncreaserFromTime(t time.Time) int64 { year := t.Year() - startYear day := t.YearDay() secs := 60*60*t.Hour() + 60*t.Minute() + t.Second() s := fmt.Sprintf("%d%d%05d", year, day, secs) v, _ := strconv.ParseInt(s, 10, 64) return v } type Mist struct { sync.Mutex // 互斥锁 increas int64 // 自增数 saltA int64 // 随机因子一 saltB int64 // 随机因子二 } /* 初始化 Mist 结构体*/ func NewMist(c int64) *Mist { mist := Mist{increas: c} return &mist } /* 生成唯一编号 */ func (c *Mist) Generate() int64 { c.Lock() defer c.Unlock() c.increas++ // 获取随机因子数值 | 使用真随机函数提高性能 randA, _ := c.newRand() c.saltA = randA.Int64() randB, _ := c.newRand() c.saltB = randB.Int64() // 通过位运算实现自动占位 mist := int64((c.increas << increasShift) | (c.saltA << saltShift) | c.saltB) return mist } func (c Mist) newRand() (*big.Int, error) { return rand.Int(rand.Reader, big.NewInt(255)) } func main() { // 使用方法 // mist := NewMist(NewIncreaserFromTime(time.Now())) mist := NewMist(31175572) m := make(map[int64]int) for i := 0; i < 10; i++ { v := mist.Generate() if _, ok := m[v]; ok { fmt.Println(v, i) } m[v] = i fmt.Println(v) } }