-
Notifications
You must be signed in to change notification settings - Fork 0
/
addressscheme.go
79 lines (66 loc) · 1.67 KB
/
addressscheme.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package hsbas
import (
"bytes"
"hash/fnv"
"net"
"time"
)
type addressScheme struct {
currentTimeStamp uint64
sequenceNumber uint64
machineNumber uint64
}
func NewAddressScheme() *addressScheme {
n := &addressScheme{}
n.machineNumber = n.GetNodeNumber()
n.currentTimeStamp = 0
n.sequenceNumber = 0
return n
}
func (as *addressScheme) GetCurrentUnixTimestampAsMilliSeconds() uint64 {
return uint64(time.Now().UnixNano() / int64(time.Millisecond))
}
func (as *addressScheme) GetCustomTimestampAsMilliSeconds() uint64 {
return as.GetCurrentUnixTimestampAsMilliSeconds() - 1546300800000
}
func (as *addressScheme) GetStringHash(data string) uint64 {
h := fnv.New32a()
_, _ = h.Write([]byte(data))
return uint64(h.Sum32())
}
func (as *addressScheme) GetMacAddress() (address string) {
interfaces, err := net.Interfaces()
if err == nil {
for _, i := range interfaces {
if i.Flags&net.FlagUp != 0 && bytes.Compare(i.HardwareAddr, nil) != 0 {
address = i.HardwareAddr.String()
break
}
}
}
return
}
func (as *addressScheme) GetNodeNumber() uint64 {
machineId, err := machineID()
if err != nil {
machineId = as.GetMacAddress()
}
if len(machineId) == 0 {
machineId = randStringBytes(32)
}
return as.GetStringHash(machineId) % 1024
}
func (as *addressScheme) GetUniqueUint64() uint64 {
for {
delta := as.GetCustomTimestampAsMilliSeconds() - as.currentTimeStamp
if delta > 0 {
as.currentTimeStamp = as.GetCustomTimestampAsMilliSeconds()
as.sequenceNumber = as.sequenceNumber + 1
if as.sequenceNumber > 4095 {
as.sequenceNumber = 0
}
break
}
}
return (as.currentTimeStamp << 22) | (as.machineNumber << 12) | as.sequenceNumber
}