github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/random/int64.go (about) 1 /* 2 * 薄雾算法 github.com/asyncins/mist 3 * 4 * 1 2 48 56 64 5 * +------+-----------------------------------------------------+----------+----------+ 6 * retain | incr | salt | sequence | 7 * +------+-----------------------------------------------------+----------+----------+ 8 * 0 | 0000000000 0000000000 0000000000 0000000000 0000000 | 00000000 | 00000000 | 9 * +------+-----------------------------------------------------+------------+--------+ 10 * 11 * 0. 最高位,占 1 位,保持为 0,使得值永远为正数; 12 * 1. 自增数,占 47 位,自增数在高位能保证结果值呈递增态势,遂低位可以为所欲为; 13 * 2. 随机因子一,占 8 位,上限数值 255,使结果值不可预测; 14 * 3. 随机因子二,占 8 位,上限数值 255,使结果值不可预测; 15 * 16 * 编号上限为百万亿级,上限值计算为 140737488355327 即 int64(1 << 47 - 1),假设每天取值 10 亿,能使用 385+ 年 17 */ 18 package random 19 20 import ( 21 "crypto/rand" 22 "math/big" 23 "sync" 24 ) 25 26 const saltBit = uint(8) // 随机因子二进制位数 27 const saltShift = uint(8) // 随机因子移位数 28 const incrShift = saltBit + saltShift // 自增数移位数 29 var defaultMist *Mist 30 31 type Mist struct { 32 sync.Mutex // 互斥锁 33 incr uint64 // 自增数 34 saltA uint64 // 随机因子一 35 saltB uint64 // 随机因子二 36 } 37 38 func init() { 39 defaultMist = NewMist() 40 } 41 42 func Int64() uint64 { 43 return defaultMist.Generate() 44 } 45 46 func NewMist(incr ...uint64) *Mist { 47 var i uint64 = 1 48 if len(incr) > 0 && incr[0] > 0 { 49 i = incr[0] 50 } 51 return &Mist{incr: i} 52 } 53 54 func (c *Mist) Generate() uint64 { 55 c.Lock() 56 c.incr++ 57 // 获取随机因子数值 | 使用真随机函数提高性能 58 randA, _ := rand.Int(rand.Reader, big.NewInt(255)) 59 c.saltA = randA.Uint64() 60 randB, _ := rand.Int(rand.Reader, big.NewInt(255)) 61 c.saltB = randB.Uint64() 62 // 实现自动占位 63 mist := (c.incr << incrShift) | (c.saltA << saltShift) | c.saltB 64 c.Unlock() 65 return mist 66 }