/
uuid-v.go
executable file
·102 lines (89 loc) · 3.45 KB
/
uuid-v.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package kee
import(
"encoding/binary"
"crypto/md5"
"crypto/sha1"
"errors"
"hash"
)
// NewV1 returns a Version 1 UUID based on the current NodeID and clock
// sequence, and the current time. If the NodeID has not been set by SetNodeID
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
// be set NewUUID returns nil. If clock sequence has not been set by
// SetClockSequence then it will be set automatically. If GetTime fails to
// return the current NewUUID returns nil.
func (c UUIDCtrl) NewV1() (KUUID, error) {
if node.nodeID == nil {
c.SetNodeInterface("")
}
now, err := GetTime()
if err != nil {
return c.newInst([]byte{}, err)
}
bytes := make([]byte, 16)
timeLow := uint32(now & 0xffffffff)
timeMid := uint16((now >> 32) & 0xffff)
timeHi := uint16((now >> 48) & 0x0fff)
timeHi |= 0x1000 // Version 1
binary.BigEndian.PutUint32(bytes[0:], timeLow)
binary.BigEndian.PutUint16(bytes[4:], timeMid)
binary.BigEndian.PutUint16(bytes[6:], timeHi)
binary.BigEndian.PutUint16(bytes[8:], clockSeq)
copy(bytes[10:], node.nodeID)
return c.newInst(bytes, nil)
}
// NewV2 is highly performant; may need some refactoring
func (c UUIDCtrl) NewV2() (KUUID, error) {
return KUUID{}, errors.New("no")
}
// NewV3 returns a new MD5 (Version 3) UUID based on the
// supplied name space and data.
// Furst
func (c UUIDCtrl) NewV3(id KUUID, data []byte) (KUUID, error) {
space := id.slc
return c.newInst(c.newHash(md5.New(), space, data, 3), nil)
}
// NewV4 returns a Random (Version 4) UUID or panics.
//
// The strength of the UUIDs is based on the strength of the crypto/rand
// package.
//
// A note about uniqueness derived from from the UUID Wikipedia entry:
//
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
// hit by a meteorite is estimated to be one chance in 17 billion, that
// means the probability is about 0.00000000006 (6 × 10−11),
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate.
func (c UUIDCtrl) NewV4() (KUUID, error) {
bytes := make([]byte, 16)
randomBits(bytes)
bytes[6] = (bytes[6] & 0x0f) | 0x40
bytes[8] = (bytes[8] & 0x3f) | 0x80
return c.newInst(bytes, nil)
}
// NewV5 returns a new SHA1 (Version 5) UUID based on the
// supplied name space and data.
func (c UUIDCtrl) NewV5(id KUUID, data []byte) (KUUID, error) {
space := id.slc
return c.newInst(c.newHash(sha1.New(), space, data, 5), nil)
}
// newHash returns a new UUID dervied from the hash of space concatenated with
// data generated by h. The hash should be at least 16 byte in length. The
// first 16 bytes of the hash are used to form the UUID. The version of the
// UUID will be the lower 4 bits of version. NewHash is used to implement
// NewV3 and NewV5.
func (_ UUIDCtrl) newHash(h hash.Hash, space []byte, data []byte, version int) []byte {
h.Reset()
h.Write(space)
h.Write([]byte(data))
s := h.Sum(nil)
bytes := make([]byte, 16)
copy(bytes, s)
bytes[6] = (bytes[6] & 0x0f) | uint8((version&0xf)<<4)
bytes[8] = (bytes[8] & 0x3f) | 0x80 // RFC 4122 variant
return bytes
}