snowflake.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // 落雪算法 来源:Twitter snowflake
  2. // 实现目标:
  3. // 可以定义起始时间,节点ID位数,步长位数,时间单位
  4. // 避免所有对象都使用同一个序列,
  5. // 常规设置:1. 64位ID,最高位是符号位,不用,时间戳版本(41位时间戳, 69年),节点ID + 步长共22位,时间单位1MS
  6. // 时间单位1000ms(1s),(31时间,68年),节点ID + 步长共32位,
  7. // 修改时间: 20241128
  8. package snowflake
  9. import (
  10. "encoding/base64"
  11. "encoding/binary"
  12. "errors"
  13. "fmt"
  14. "strconv"
  15. "sync"
  16. "time"
  17. )
  18. // epochS: time in seconds,起始时间
  19. // nodeBits: the number of bits to use for node id, 节点ID位数,
  20. // stepBits: the number of bits to use for sequence number, 步长位数
  21. // node:节点ID
  22. const encodeBase32Map = "ybndrfg8ejkmcpqxot1uwisza345h769"
  23. var decodeBase32Map [256]byte
  24. const encodeBase58Map = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
  25. var decodeBase58Map [256]byte
  26. // A JSONSyntaxError is returned from UnmarshalJSON if an invalid ID is provided.
  27. type JSONSyntaxError struct{ original []byte }
  28. func (j JSONSyntaxError) Error() string {
  29. return fmt.Sprintf("invalid snowflake ID %q", string(j.original))
  30. }
  31. // ErrInvalidBase58 is returned by ParseBase58 when given an invalid []byte
  32. var ErrInvalidBase58 = errors.New("invalid base58")
  33. // ErrInvalidBase32 is returned by ParseBase32 when given an invalid []byte
  34. var ErrInvalidBase32 = errors.New("invalid base32")
  35. // Create maps for decoding Base58/Base32.
  36. // This speeds up the process tremendously.
  37. func init() {
  38. for i := 0; i < len(encodeBase58Map); i++ {
  39. decodeBase58Map[i] = 0xFF
  40. }
  41. for i := 0; i < len(encodeBase58Map); i++ {
  42. decodeBase58Map[encodeBase58Map[i]] = byte(i)
  43. }
  44. for i := 0; i < len(encodeBase32Map); i++ {
  45. decodeBase32Map[i] = 0xFF
  46. }
  47. for i := 0; i < len(encodeBase32Map); i++ {
  48. decodeBase32Map[encodeBase32Map[i]] = byte(i)
  49. }
  50. }
  51. // A Node struct holds the basic information needed for a snowflake generator
  52. // node
  53. type Node struct {
  54. mu sync.Mutex
  55. epoch time.Time
  56. time int64
  57. node int64
  58. step int64
  59. unitTime int64
  60. nodeMax int64
  61. // nodeMask int64
  62. stepMask int64
  63. timeMax int64
  64. timeShift uint8
  65. nodeShift uint8
  66. }
  67. // An ID is a custom type used for a snowflake ID. This is used so we can
  68. // attach methods onto the ID.
  69. type ID int64
  70. // NewNode returns a new snowflake node that can be used to generate snowflake
  71. // IDs
  72. func NewNode(node int64, nodeBits uint8, stepBits uint8, unitTime int64, epochS int64) (*Node, error) {
  73. if unitTime <= 0 {
  74. unitTime = 1
  75. }
  76. n := Node{}
  77. n.node = node
  78. n.nodeMax = -1 ^ (-1 << nodeBits)
  79. // n.nodeMask = n.nodeMax << stepBits
  80. n.stepMask = -1 ^ (-1 << stepBits)
  81. n.timeShift = nodeBits + stepBits
  82. n.nodeShift = stepBits
  83. n.unitTime = unitTime
  84. timeBits := 63 - n.timeShift
  85. n.timeMax = -1 ^ (-1 << timeBits)
  86. if n.node < 0 || n.node > n.nodeMax {
  87. return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(n.nodeMax, 10))
  88. }
  89. var curTime = time.Now()
  90. // add time.Duration to curTime to make sure we use the monotonic clock if available
  91. n.epoch = curTime.Add(time.Unix(epochS, 0).Sub(curTime))
  92. return &n, nil
  93. }
  94. // Generate creates and returns a unique snowflake ID
  95. // To help guarantee uniqueness
  96. // - Make sure your system is keeping accurate system time
  97. // - Make sure you never have multiple nodes running with the same node ID
  98. func (n *Node) Generate() ID {
  99. n.mu.Lock()
  100. now := (time.Since(n.epoch).Nanoseconds() / 1000000) / n.unitTime
  101. if now == n.time {
  102. n.step = (n.step + 1) & n.stepMask
  103. if n.step == 0 {
  104. for now <= n.time {
  105. now = (time.Since(n.epoch).Nanoseconds() / 1000000) / n.unitTime
  106. }
  107. }
  108. } else {
  109. n.step = 0
  110. }
  111. n.time = now
  112. r := ID((now)<<n.timeShift |
  113. (n.node << n.nodeShift) |
  114. (n.step),
  115. )
  116. n.mu.Unlock()
  117. return r
  118. }
  119. func (n *Node) RollGenerate() ID {
  120. n.mu.Lock()
  121. now := (time.Since(n.epoch).Nanoseconds() / 1000000) / n.unitTime
  122. if now == n.time {
  123. n.step = (n.step + 1) & n.stepMask
  124. if n.step == 0 {
  125. for now <= n.time {
  126. now = (time.Since(n.epoch).Nanoseconds() / 1000000) / n.unitTime
  127. }
  128. }
  129. } else {
  130. n.step = 0
  131. }
  132. n.time = now
  133. now2 := now & n.timeMax
  134. r := ID((now2)<<n.timeShift |
  135. (n.node << n.nodeShift) |
  136. (n.step),
  137. )
  138. n.mu.Unlock()
  139. return r
  140. }
  141. // Int64 returns an int64 of the snowflake ID
  142. func (f ID) Int64() int64 {
  143. return int64(f)
  144. }
  145. // String returns a string of the snowflake ID
  146. func (f ID) String() string {
  147. return strconv.FormatInt(int64(f), 10)
  148. }
  149. // ParseString converts a string into a snowflake ID
  150. func ParseString(id string) (ID, error) {
  151. i, err := strconv.ParseInt(id, 10, 64)
  152. return ID(i), err
  153. }
  154. // Base2 returns a string base2 of the snowflake ID
  155. func (f ID) Base2() string {
  156. return strconv.FormatInt(int64(f), 2)
  157. }
  158. // ParseBase2 converts a Base2 string into a snowflake ID
  159. func ParseBase2(id string) (ID, error) {
  160. i, err := strconv.ParseInt(id, 2, 64)
  161. return ID(i), err
  162. }
  163. // Base32 uses the z-base-32 character set but encodes and decodes similar
  164. // to base58, allowing it to create an even smaller result string.
  165. // NOTE: There are many different base32 implementations so becareful when
  166. // doing any interoperation.
  167. func (f ID) Base32() string {
  168. if f < 32 {
  169. return string(encodeBase32Map[f])
  170. }
  171. b := make([]byte, 0, 12)
  172. for f >= 32 {
  173. b = append(b, encodeBase32Map[f%32])
  174. f /= 32
  175. }
  176. b = append(b, encodeBase32Map[f])
  177. for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
  178. b[x], b[y] = b[y], b[x]
  179. }
  180. return string(b)
  181. }
  182. // ParseBase32 parses a base32 []byte into a snowflake ID
  183. // NOTE: There are many different base32 implementations so becareful when
  184. // doing any interoperation.
  185. func ParseBase32(b []byte) (ID, error) {
  186. var id int64
  187. for i := range b {
  188. if decodeBase32Map[b[i]] == 0xFF {
  189. return -1, ErrInvalidBase32
  190. }
  191. id = id*32 + int64(decodeBase32Map[b[i]])
  192. }
  193. return ID(id), nil
  194. }
  195. // Base36 returns a base36 string of the snowflake ID
  196. func (f ID) Base36() string {
  197. return strconv.FormatInt(int64(f), 36)
  198. }
  199. // ParseBase36 converts a Base36 string into a snowflake ID
  200. func ParseBase36(id string) (ID, error) {
  201. i, err := strconv.ParseInt(id, 36, 64)
  202. return ID(i), err
  203. }
  204. // Base58 returns a base58 string of the snowflake ID
  205. func (f ID) Base58() string {
  206. if f < 58 {
  207. return string(encodeBase58Map[f])
  208. }
  209. b := make([]byte, 0, 11)
  210. for f >= 58 {
  211. b = append(b, encodeBase58Map[f%58])
  212. f /= 58
  213. }
  214. b = append(b, encodeBase58Map[f])
  215. for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
  216. b[x], b[y] = b[y], b[x]
  217. }
  218. return string(b)
  219. }
  220. // ParseBase58 parses a base58 []byte into a snowflake ID
  221. func ParseBase58(b []byte) (ID, error) {
  222. var id int64
  223. for i := range b {
  224. if decodeBase58Map[b[i]] == 0xFF {
  225. return -1, ErrInvalidBase58
  226. }
  227. id = id*58 + int64(decodeBase58Map[b[i]])
  228. }
  229. return ID(id), nil
  230. }
  231. // Base64 returns a base64 string of the snowflake ID
  232. func (f ID) Base64() string {
  233. return base64.StdEncoding.EncodeToString(f.Bytes())
  234. }
  235. // ParseBase64 converts a base64 string into a snowflake ID
  236. func ParseBase64(id string) (ID, error) {
  237. b, err := base64.StdEncoding.DecodeString(id)
  238. if err != nil {
  239. return -1, err
  240. }
  241. return ParseBytes(b)
  242. }
  243. // Bytes returns a byte slice of the snowflake ID
  244. func (f ID) Bytes() []byte {
  245. return []byte(f.String())
  246. }
  247. // ParseBytes converts a byte slice into a snowflake ID
  248. func ParseBytes(id []byte) (ID, error) {
  249. i, err := strconv.ParseInt(string(id), 10, 64)
  250. return ID(i), err
  251. }
  252. // IntBytes returns an array of bytes of the snowflake ID, encoded as a
  253. // big endian integer.
  254. func (f ID) IntBytes() [8]byte {
  255. var b [8]byte
  256. binary.BigEndian.PutUint64(b[:], uint64(f))
  257. return b
  258. }
  259. // ParseIntBytes converts an array of bytes encoded as big endian integer as
  260. // a snowflake ID
  261. func ParseIntBytes(id [8]byte) ID {
  262. return ID(int64(binary.BigEndian.Uint64(id[:])))
  263. }
  264. // 时间41毫秒(69年), node+step=22
  265. func NewMsNode(node int64, nodeBits uint8) (*Node, error) {
  266. startTs := time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
  267. stepBits := uint8(22 - nodeBits)
  268. return NewNode(node, nodeBits, stepBits, 1, startTs.Unix())
  269. }
  270. // 时间41秒(68年), node+step=32
  271. func NewSecondNode(node int64, nodeBits uint8) (*Node, error) {
  272. startTs := time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
  273. stepBits := uint8(32 - nodeBits)
  274. return NewNode(node, nodeBits, stepBits, 1000, startTs.Unix())
  275. }
  276. // 时间毫秒30(298小时),node10(1023),步长23( 8388608 个)
  277. // 调用RollGenerate产生时间循环ID
  278. func NewTimeRoolNode(node int64, nodeBits uint8) (*Node, error) {
  279. startTs := time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
  280. stepBits := uint8(33 - nodeBits)
  281. return NewNode(node, nodeBits, stepBits, 1, startTs.Unix())
  282. }
  283. func testSnowflakeNode() {
  284. startTs := time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
  285. seq, err := NewNode(0, 0, 22, 1, startTs.Unix())
  286. if err != nil {
  287. return
  288. }
  289. seq.Generate().Int64()
  290. seq2, err2 := NewNode(0, 0, 32, 1000, startTs.Unix())
  291. if err2 != nil {
  292. return
  293. }
  294. seq2.Generate().Int64()
  295. }