snowflake.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // Package snowflake provides a very simple Twitter snowflake generator and parser.
  2. package snowflake
  3. import (
  4. "encoding/base64"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "strconv"
  9. "sync"
  10. "time"
  11. )
  12. var (
  13. // Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds
  14. // You may customize this to set a different epoch for your application.
  15. Epoch int64 = 1704038400000 //2024-01-01 00:00:00
  16. // NodeBits holds the number of bits to use for Node
  17. // Remember, you have a total 22 bits to share between Node/Step
  18. NodeBits uint8 = 10
  19. // StepBits holds the number of bits to use for Step
  20. // Remember, you have a total 22 bits to share between Node/Step
  21. StepBits uint8 = 12
  22. // DEPRECATED: the below four variables will be removed in a future release.
  23. mu sync.Mutex
  24. nodeMax int64 = -1 ^ (-1 << NodeBits)
  25. nodeMask = nodeMax << StepBits
  26. stepMask int64 = -1 ^ (-1 << StepBits)
  27. timeShift = NodeBits + StepBits
  28. nodeShift = StepBits
  29. )
  30. const encodeBase32Map = "ybndrfg8ejkmcpqxot1uwisza345h769"
  31. var decodeBase32Map [256]byte
  32. const encodeBase58Map = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
  33. var decodeBase58Map [256]byte
  34. // A JSONSyntaxError is returned from UnmarshalJSON if an invalid ID is provided.
  35. type JSONSyntaxError struct{ original []byte }
  36. func (j JSONSyntaxError) Error() string {
  37. return fmt.Sprintf("invalid snowflake ID %q", string(j.original))
  38. }
  39. // ErrInvalidBase58 is returned by ParseBase58 when given an invalid []byte
  40. var ErrInvalidBase58 = errors.New("invalid base58")
  41. // ErrInvalidBase32 is returned by ParseBase32 when given an invalid []byte
  42. var ErrInvalidBase32 = errors.New("invalid base32")
  43. // Create maps for decoding Base58/Base32.
  44. // This speeds up the process tremendously.
  45. func init() {
  46. for i := 0; i < len(decodeBase58Map); i++ {
  47. decodeBase58Map[i] = 0xFF
  48. }
  49. for i := 0; i < len(encodeBase58Map); i++ {
  50. decodeBase58Map[encodeBase58Map[i]] = byte(i)
  51. }
  52. for i := 0; i < len(decodeBase32Map); i++ {
  53. decodeBase32Map[i] = 0xFF
  54. }
  55. for i := 0; i < len(encodeBase32Map); i++ {
  56. decodeBase32Map[encodeBase32Map[i]] = byte(i)
  57. }
  58. }
  59. // A Node struct holds the basic information needed for a snowflake generator
  60. // node
  61. type Node struct {
  62. mu sync.Mutex
  63. epoch time.Time
  64. time int64
  65. node int64
  66. step int64
  67. nodeMax int64
  68. nodeMask int64
  69. stepMask int64
  70. timeShift uint8
  71. nodeShift uint8
  72. }
  73. // An ID is a custom type used for a snowflake ID. This is used so we can
  74. // attach methods onto the ID.
  75. type ID int64
  76. // NewNode returns a new snowflake node that can be used to generate snowflake
  77. // IDs
  78. func NewNode(node int64) (*Node, error) {
  79. if NodeBits+StepBits > 22 {
  80. return nil, errors.New("Remember, you have a total 22 bits to share between Node/Step")
  81. }
  82. // re-calc in case custom NodeBits or StepBits were set
  83. // DEPRECATED: the below block will be removed in a future release.
  84. mu.Lock()
  85. nodeMax = -1 ^ (-1 << NodeBits)
  86. nodeMask = nodeMax << StepBits
  87. stepMask = -1 ^ (-1 << StepBits)
  88. timeShift = NodeBits + StepBits
  89. nodeShift = StepBits
  90. mu.Unlock()
  91. n := Node{}
  92. n.node = node
  93. n.nodeMax = -1 ^ (-1 << NodeBits)
  94. n.nodeMask = n.nodeMax << StepBits
  95. n.stepMask = -1 ^ (-1 << StepBits)
  96. n.timeShift = NodeBits + StepBits
  97. n.nodeShift = StepBits
  98. if n.node < 0 || n.node > n.nodeMax {
  99. return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(n.nodeMax, 10))
  100. }
  101. var curTime = time.Now()
  102. // add time.Duration to curTime to make sure we use the monotonic clock if available
  103. n.epoch = curTime.Add(time.Unix(Epoch/1000, (Epoch%1000)*1000000).Sub(curTime))
  104. return &n, nil
  105. }
  106. // Generate creates and returns a unique snowflake ID
  107. // To help guarantee uniqueness
  108. // - Make sure your system is keeping accurate system time
  109. // - Make sure you never have multiple nodes running with the same node ID
  110. func (n *Node) Generate() ID {
  111. n.mu.Lock()
  112. defer n.mu.Unlock()
  113. now := time.Since(n.epoch).Milliseconds()
  114. if now == n.time {
  115. //同一毫秒生成,id+1
  116. n.step = (n.step + 1) & n.stepMask
  117. //等于零表示4096个号用完了
  118. if n.step == 0 {
  119. //方案1 从未来借时间
  120. //now = now + 1
  121. //方案2 等待下一毫秒
  122. for now <= n.time {
  123. now = time.Since(n.epoch).Milliseconds()
  124. }
  125. }
  126. } else if now > n.time {
  127. n.step = 0
  128. } else {
  129. //解决时钟回拨的问题
  130. if n.time-now > 2000 {
  131. fmt.Println("system time exception")
  132. }
  133. //不超过5秒,从未来借时间生成id
  134. n.step = (n.step + 1) & n.stepMask
  135. if n.step == 0 {
  136. now = now + 1
  137. }
  138. }
  139. n.time = now
  140. r := ID((now)<<n.timeShift |
  141. (n.node << n.nodeShift) |
  142. (n.step),
  143. )
  144. return r
  145. }
  146. // Int64 returns an int64 of the snowflake ID
  147. func (f ID) Int64() int64 {
  148. return int64(f)
  149. }
  150. // ParseInt64 converts an int64 into a snowflake ID
  151. func ParseInt64(id int64) ID {
  152. return ID(id)
  153. }
  154. // String returns a string of the snowflake ID
  155. func (f ID) String() string {
  156. return strconv.FormatInt(int64(f), 10)
  157. }
  158. // ParseString converts a string into a snowflake ID
  159. func ParseString(id string) (ID, error) {
  160. i, err := strconv.ParseInt(id, 10, 64)
  161. return ID(i), err
  162. }
  163. // Base2 returns a string base2 of the snowflake ID
  164. func (f ID) Base2() string {
  165. return strconv.FormatInt(int64(f), 2)
  166. }
  167. // ParseBase2 converts a Base2 string into a snowflake ID
  168. func ParseBase2(id string) (ID, error) {
  169. i, err := strconv.ParseInt(id, 2, 64)
  170. return ID(i), err
  171. }
  172. // Base32 uses the z-base-32 character set but encodes and decodes similar
  173. // to base58, allowing it to create an even smaller result string.
  174. // NOTE: There are many different base32 implementations so becareful when
  175. // doing any interoperation.
  176. func (f ID) Base32() string {
  177. if f < 32 {
  178. return string(encodeBase32Map[f])
  179. }
  180. b := make([]byte, 0, 12)
  181. for f >= 32 {
  182. b = append(b, encodeBase32Map[f%32])
  183. f /= 32
  184. }
  185. b = append(b, encodeBase32Map[f])
  186. for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
  187. b[x], b[y] = b[y], b[x]
  188. }
  189. return string(b)
  190. }
  191. // ParseBase32 parses a base32 []byte into a snowflake ID
  192. // NOTE: There are many different base32 implementations so becareful when
  193. // doing any interoperation.
  194. func ParseBase32(b []byte) (ID, error) {
  195. var id int64
  196. for i := range b {
  197. if decodeBase32Map[b[i]] == 0xFF {
  198. return -1, ErrInvalidBase32
  199. }
  200. id = id*32 + int64(decodeBase32Map[b[i]])
  201. }
  202. return ID(id), nil
  203. }
  204. // Base36 returns a base36 string of the snowflake ID
  205. func (f ID) Base36() string {
  206. return strconv.FormatInt(int64(f), 36)
  207. }
  208. // ParseBase36 converts a Base36 string into a snowflake ID
  209. func ParseBase36(id string) (ID, error) {
  210. i, err := strconv.ParseInt(id, 36, 64)
  211. return ID(i), err
  212. }
  213. // Base58 returns a base58 string of the snowflake ID
  214. func (f ID) Base58() string {
  215. if f < 58 {
  216. return string(encodeBase58Map[f])
  217. }
  218. b := make([]byte, 0, 11)
  219. for f >= 58 {
  220. b = append(b, encodeBase58Map[f%58])
  221. f /= 58
  222. }
  223. b = append(b, encodeBase58Map[f])
  224. for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
  225. b[x], b[y] = b[y], b[x]
  226. }
  227. return string(b)
  228. }
  229. // ParseBase58 parses a base58 []byte into a snowflake ID
  230. func ParseBase58(b []byte) (ID, error) {
  231. var id int64
  232. for i := range b {
  233. if decodeBase58Map[b[i]] == 0xFF {
  234. return -1, ErrInvalidBase58
  235. }
  236. id = id*58 + int64(decodeBase58Map[b[i]])
  237. }
  238. return ID(id), nil
  239. }
  240. // Base64 returns a base64 string of the snowflake ID
  241. func (f ID) Base64() string {
  242. return base64.StdEncoding.EncodeToString(f.Bytes())
  243. }
  244. // ParseBase64 converts a base64 string into a snowflake ID
  245. func ParseBase64(id string) (ID, error) {
  246. b, err := base64.StdEncoding.DecodeString(id)
  247. if err != nil {
  248. return -1, err
  249. }
  250. return ParseBytes(b)
  251. }
  252. // Bytes returns a byte slice of the snowflake ID
  253. func (f ID) Bytes() []byte {
  254. return []byte(f.String())
  255. }
  256. // ParseBytes converts a byte slice into a snowflake ID
  257. func ParseBytes(id []byte) (ID, error) {
  258. i, err := strconv.ParseInt(string(id), 10, 64)
  259. return ID(i), err
  260. }
  261. // IntBytes returns an array of bytes of the snowflake ID, encoded as a
  262. // big endian integer.
  263. func (f ID) IntBytes() [8]byte {
  264. var b [8]byte
  265. binary.BigEndian.PutUint64(b[:], uint64(f))
  266. return b
  267. }
  268. // ParseIntBytes converts an array of bytes encoded as big endian integer as
  269. // a snowflake ID
  270. func ParseIntBytes(id [8]byte) ID {
  271. return ID(int64(binary.BigEndian.Uint64(id[:])))
  272. }
  273. // Time returns an int64 unix timestamp in milliseconds of the snowflake ID time
  274. // DEPRECATED: the below function will be removed in a future release.
  275. func (f ID) Time() int64 {
  276. return (int64(f) >> timeShift) + Epoch
  277. }
  278. // Node returns an int64 of the snowflake ID node number
  279. // DEPRECATED: the below function will be removed in a future release.
  280. func (f ID) Node() int64 {
  281. return int64(f) & nodeMask >> nodeShift
  282. }
  283. // Step returns an int64 of the snowflake step (or sequence) number
  284. // DEPRECATED: the below function will be removed in a future release.
  285. func (f ID) Step() int64 {
  286. return int64(f) & stepMask
  287. }
  288. // MarshalJSON returns a json byte array string of the snowflake ID.
  289. func (f ID) MarshalJSON() ([]byte, error) {
  290. buff := make([]byte, 0, 22)
  291. buff = append(buff, '"')
  292. buff = strconv.AppendInt(buff, int64(f), 10)
  293. buff = append(buff, '"')
  294. return buff, nil
  295. }
  296. // UnmarshalJSON converts a json byte array of a snowflake ID into an ID type.
  297. func (f *ID) UnmarshalJSON(b []byte) error {
  298. if len(b) < 3 || b[0] != '"' || b[len(b)-1] != '"' {
  299. return JSONSyntaxError{b}
  300. }
  301. i, err := strconv.ParseInt(string(b[1:len(b)-1]), 10, 64)
  302. if err != nil {
  303. return err
  304. }
  305. *f = ID(i)
  306. return nil
  307. }