cuelang.org/go@v0.10.1/pkg/uuid/uuid.go (about) 1 // Copyright 2021 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package uuid defines functionality for creating UUIDs as defined in RFC 4122. 16 // 17 // Currently only Version 5 (SHA1) and Version 3 (MD5) are supported. 18 package uuid 19 20 import ( 21 "fmt" 22 "math/big" 23 "regexp" 24 "sync" 25 26 "github.com/google/uuid" 27 ) 28 29 var valid = sync.OnceValue(func() *regexp.Regexp { 30 return regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") 31 }) 32 33 // TODO(mvdan): should Valid not use [uuid.Validate]? 34 35 // Valid can be used to define a valid Valid. 36 func Valid(s string) error { 37 if !valid().MatchString(string(s)) { 38 return fmt.Errorf("invalid UUID %q", s) 39 } 40 return nil 41 } 42 43 // Parse decodes s into a UUID or returns an error. Both the standard UUID forms 44 // of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and 45 // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the 46 // Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex 47 // encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. 48 func Parse(s string) (string, error) { 49 x, err := uuid.Parse(s) 50 return string(x.String()), err 51 } 52 53 // String represents a 128-bit UUID value as a string. 54 func ToString(x string) string { 55 return string(x) 56 } 57 58 // URN reports the canonical URN of a UUID. 59 func URN(x string) (string, error) { 60 u, err := uuid.Parse(string(x)) 61 if err != nil { 62 return "", err 63 } 64 return u.URN(), nil 65 } 66 67 // FromInt creates a UUID from an integer. 68 // 69 // DNS: uuid.FromInt(0x6ba7b810_9dad_11d1_80b4_00c04fd430c8) 70 func FromInt(i *big.Int) (string, error) { 71 // must be uint128 72 var buf [16]byte 73 b := i.Bytes() 74 if len(b) < 16 { 75 copy(buf[16-len(b):], b) 76 b = buf[:] 77 } 78 u, err := uuid.FromBytes(b) 79 return string(u.String()), err 80 } 81 82 // ToInt represents a UUID string as a 128-bit value. 83 func ToInt(x string) *big.Int { 84 var i big.Int 85 i.SetBytes([]byte(x[:])) 86 return &i 87 } 88 89 // Variant reports the UUID variant. 90 func Variant(x string) (int, error) { 91 u, err := uuid.Parse(string(x)) 92 if err != nil { 93 return 0, err 94 } 95 return int(u.Variant()), nil 96 } 97 98 // Version reports the UUID version. 99 func Version(x string) (int, error) { 100 u, err := uuid.Parse(string(x)) 101 if err != nil { 102 return 0, err 103 } 104 return int(u.Version()), nil 105 } 106 107 // SHA1 generates a version 5 UUID based on the supplied name space and data. 108 func SHA1(space string, data []byte) (string, error) { 109 u, err := uuid.Parse(string(space)) 110 if err != nil { 111 return "", err 112 } 113 return string(uuid.NewSHA1(u, data).String()), nil 114 } 115 116 // MD5 generates a version 3 UUID based on the supplied name space and data. 117 // Use SHA1 instead if you can. 118 func MD5(space string, data []byte) (string, error) { 119 u, err := uuid.Parse(string(space)) 120 if err != nil { 121 return "", err 122 } 123 return string(uuid.NewMD5(u, data).String()), nil 124 }