-
Notifications
You must be signed in to change notification settings - Fork 0
/
uuid.go
74 lines (67 loc) · 1.41 KB
/
uuid.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
package uuid
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
)
type (
UUID interface {
Bytes() []byte
String() string
Array() [16]byte
}
uuid [16]byte
)
// New makes a new UUID interface;
// if input len is 0, executed like uuid.New(), then it will generate a random uuid;
// if input len is 16, like uuid.New([16]byte{}...), then it will directly use the 16 bytes as the uuid;
// if input len is something other than 0 or 16, then the input seeds a new psudo-random uuid.
func New(e ...byte) (UUID, error) {
u := &uuid{}
switch len(e) {
case 0:
{
_, err := rand.Read(u[:])
if err != nil {
return nil, err
}
}
case 16:
{
copy(u[:], e)
}
default:
{
s := sha256.Sum256(e)
for i := 0; i < 32; i++ {
s = sha256.Sum256(s[:16])
}
copy(u[:], s[:16])
}
}
return u, nil
}
func (u *uuid) String() string {
return fmt.Sprintf("%x-%x-%x-%x-%x", u[:4], u[4:6], u[6:8], u[8:10], u[10:16])
}
func (u *uuid) Bytes() []byte {
return u[:]
}
func (u *uuid) Array() [16]byte {
return *u
}
func StringtoUUID(s string) (UUID, error) {
if len(strings.Split(s, "-")) != 5 {
return nil, fmt.Errorf("probably not a uuid: %s", s)
}
b, err := hex.DecodeString(strings.ReplaceAll(s, "-", ""))
if err != nil {
return nil, fmt.Errorf("probably not a uuid: %v", err)
}
if len(b) != 16 {
return nil, fmt.Errorf("probably not a uuid: %s", s)
}
return New(b...)
}