uuid.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package utils
  2. import (
  3. "errors"
  4. "fmt"
  5. "sync"
  6. "time"
  7. )
  8. func SetUuidNode(i int) {
  9. newUuid().setNodeId(i)
  10. }
  11. func GenStrUuid() string {
  12. for i := 0; i < 3; i++ {
  13. uuid, err := newUuid().generateId()
  14. if err == nil {
  15. return fmt.Sprintf("%d", uuid)
  16. }
  17. }
  18. return fmt.Sprintf("%d", time.Now().UnixMilli())
  19. }
  20. func GenUuid() int64 {
  21. for i := 0; i < 3; i++ {
  22. uuid, err := newUuid().generateId()
  23. if err == nil {
  24. return uuid
  25. }
  26. }
  27. return time.Now().UnixMilli()
  28. }
  29. func UuidToTime(uuid int64) time.Time {
  30. return newUuid().uuidToTime(uuid)
  31. }
  32. func TimeToUuid(ts time.Time) int64 {
  33. return newUuid().timeToUuid(ts)
  34. }
  35. var (
  36. rotateId = 15
  37. nodeId = 6
  38. T2018 int64 = 1514736000000
  39. )
  40. type Uuid struct {
  41. lock sync.Mutex
  42. timeId int64
  43. nodeId int
  44. rotateId int
  45. nodeIdWidth int
  46. nodeIdMask int
  47. rotateIdWidth int
  48. rotateIdMask int
  49. T201801010000 int64
  50. }
  51. var midUtil *Uuid
  52. func newUuid() *Uuid {
  53. if midUtil == nil {
  54. midUtil = &Uuid{
  55. timeId: 0,
  56. lock: sync.Mutex{},
  57. nodeIdWidth: nodeId,
  58. nodeIdMask: 0x3F,
  59. rotateIdWidth: rotateId,
  60. rotateIdMask: 0x7FFF,
  61. T201801010000: T2018,
  62. nodeId: 0,
  63. }
  64. }
  65. return midUtil
  66. }
  67. func (m *Uuid) setNodeId(i int) {
  68. m.nodeId = i
  69. return
  70. }
  71. func (m *Uuid) generateId() (int64, error) {
  72. m.lock.Lock()
  73. defer m.lock.Unlock()
  74. m.rotateId = (m.rotateId + 1) & m.rotateIdMask
  75. mid := time.Now().UnixMilli() - m.T201801010000
  76. if mid > m.timeId {
  77. m.timeId = mid
  78. m.rotateId = 1
  79. } else if mid == m.timeId {
  80. if m.rotateId == (m.rotateIdMask - 1) {
  81. for {
  82. if mid <= m.timeId {
  83. mid = time.Now().UnixMilli() - m.T201801010000
  84. } else {
  85. return m.generateId()
  86. }
  87. }
  88. }
  89. } else {
  90. if m.rotateId > (m.rotateIdMask-1)*9/10 {
  91. if m.timeId-mid < 3000 {
  92. for {
  93. if mid < m.timeId {
  94. mid = time.Now().UnixMilli() - m.T201801010000
  95. }
  96. return m.generateId()
  97. }
  98. } else {
  99. return 0, errors.New(fmt.Sprintf("Time turn back %d ms, it too long!!!", m.timeId-mid))
  100. }
  101. } else {
  102. mid = m.timeId
  103. }
  104. }
  105. mid <<= m.nodeIdWidth
  106. mid += int64(m.nodeId & m.nodeIdMask)
  107. mid <<= m.rotateIdWidth
  108. mid += int64(m.rotateId)
  109. return mid, nil
  110. }
  111. func (m *Uuid) uuidToTime(uuid int64) time.Time {
  112. uuid >>= m.nodeId + m.rotateId
  113. dateNum := uuid + T2018
  114. return time.UnixMilli(dateNum)
  115. }
  116. func (m *Uuid) timeToUuid(ts time.Time) int64 {
  117. m.lock.Lock()
  118. defer m.lock.Unlock()
  119. m.rotateId = (m.rotateId + 1) & m.rotateIdMask
  120. mid := ts.UnixMilli() - m.T201801010000
  121. mid <<= m.nodeIdWidth
  122. mid += int64(m.nodeId & m.nodeIdMask)
  123. mid <<= m.rotateIdWidth
  124. mid += int64(m.rotateId)
  125. return mid
  126. }