From 31e5b003cd5a0af4199e633a39319df94fdc5379 Mon Sep 17 00:00:00 2001 From: finlab Date: Mon, 28 Dec 2020 05:11:31 +0800 Subject: [PATCH] add example2 --- example2/main.go | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 example2/main.go diff --git a/example2/main.go b/example2/main.go new file mode 100644 index 0000000..7f1eba2 --- /dev/null +++ b/example2/main.go @@ -0,0 +1,89 @@ +/* +* 薄雾算法 +* +* 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) + } +}