add example2
This commit is contained in:
		
							
								
								
									
										89
									
								
								example2/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								example2/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user