snowflake.go 8.8 KB

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