github.com/EagleQL/Xray-core@v1.4.3/common/uuid/uuid.go (about) 1 package uuid // import "github.com/xtls/xray-core/common/uuid" 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "crypto/sha1" 7 "encoding/hex" 8 9 "github.com/xtls/xray-core/common" 10 "github.com/xtls/xray-core/common/errors" 11 ) 12 13 var ( 14 byteGroups = []int{8, 4, 4, 4, 12} 15 ) 16 17 type UUID [16]byte 18 19 // String returns the string representation of this UUID. 20 func (u *UUID) String() string { 21 bytes := u.Bytes() 22 result := hex.EncodeToString(bytes[0 : byteGroups[0]/2]) 23 start := byteGroups[0] / 2 24 for i := 1; i < len(byteGroups); i++ { 25 nBytes := byteGroups[i] / 2 26 result += "-" 27 result += hex.EncodeToString(bytes[start : start+nBytes]) 28 start += nBytes 29 } 30 return result 31 } 32 33 // Bytes returns the bytes representation of this UUID. 34 func (u *UUID) Bytes() []byte { 35 return u[:] 36 } 37 38 // Equals returns true if this UUID equals another UUID by value. 39 func (u *UUID) Equals(another *UUID) bool { 40 if u == nil && another == nil { 41 return true 42 } 43 if u == nil || another == nil { 44 return false 45 } 46 return bytes.Equal(u.Bytes(), another.Bytes()) 47 } 48 49 // New creates a UUID with random value. 50 func New() UUID { 51 var uuid UUID 52 common.Must2(rand.Read(uuid.Bytes())) 53 uuid[6] = (uuid[6] & 0x0f) | (4 << 4) 54 uuid[8] = (uuid[8]&(0xff>>2) | (0x02 << 6)) 55 return uuid 56 } 57 58 // ParseBytes converts a UUID in byte form to object. 59 func ParseBytes(b []byte) (UUID, error) { 60 var uuid UUID 61 if len(b) != 16 { 62 return uuid, errors.New("invalid UUID: ", b) 63 } 64 copy(uuid[:], b) 65 return uuid, nil 66 } 67 68 // ParseString converts a UUID in string form to object. 69 func ParseString(str string) (UUID, error) { 70 var uuid UUID 71 72 text := []byte(str) 73 if l := len(text); l < 32 || l > 36 { 74 if l == 0 || l > 30 { 75 return uuid, errors.New("invalid UUID: ", str) 76 } 77 h := sha1.New() 78 h.Write(uuid[:]) 79 h.Write(text) 80 u := h.Sum(nil)[:16] 81 u[6] = (u[6] & 0x0f) | (5 << 4) 82 u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) 83 copy(uuid[:], u) 84 return uuid, nil 85 } 86 87 b := uuid.Bytes() 88 89 for _, byteGroup := range byteGroups { 90 if text[0] == '-' { 91 text = text[1:] 92 } 93 94 if _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup]); err != nil { 95 return uuid, err 96 } 97 98 text = text[byteGroup:] 99 b = b[byteGroup/2:] 100 } 101 102 return uuid, nil 103 }