This repository was archived by the owner on May 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUUID.go
57 lines (48 loc) · 1.4 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
package main
import (
"crypto/md5"
"strconv"
"strings"
)
// UUID is modeled after java.util.UUID
// Holds the most significant and least significant bits of a UUID
type UUID struct {
msb uint64
lsb uint64
}
// NewNameUUIDFromBytes creates a type 3 - name based - UUID
// based on the specified byte array.
// Corresponds to java.util.UUID#nameUUIDFromBytes
func NewNameUUIDFromBytes(bytes []byte) *UUID {
md5Hash := md5.Sum(bytes)
md5Hash[6] &= 0x0f /* clear version */
md5Hash[6] |= 0x30 /* set to version 3 */
md5Hash[8] &= 0x3f /* clear variant */
md5Hash[8] |= 0x80 /* set to IETF variant */
var msb uint64
var lsb uint64
for i := 0; i < 8; i++ {
msb = (msb << 8) | (uint64(md5Hash[i]) & 0xff)
}
for i := 8; i < 16; i++ {
lsb = (lsb << 8) | (uint64(md5Hash[i]) & 0xff)
}
return &UUID{msb, lsb}
}
// String returns a string representing this UUID.
// Corresponds to java.util.UUID#toString
func (uuid *UUID) String() string {
parts := make([]string, 5)
parts[0] = digits(uuid.msb>>32, 8)
parts[1] = digits(uuid.msb>>16, 4)
parts[2] = digits(uuid.msb, 4)
parts[3] = digits(uuid.lsb>>48, 4)
parts[4] = digits(uuid.lsb, 12)
return strings.Join(parts, "-")
}
// Corresponds to java.util.UUID#digits
func digits(val uint64, digits uint) string {
hi := 1 << (digits * 4)
result := uint64(hi) | (val & (uint64(hi) - uint64(1)))
return strconv.FormatInt(int64(result), 16)[1:]
}