common/uuid.go (61 lines of code) (raw):

package common import ( "crypto/rand" "encoding/json" "fmt" "unsafe" ) // The JobID reserved variants. const ( reservedRFC4122 byte = 0x40 guidFormat = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" ) // A UUID representation compliant with specification in RFC 4122 document. type UUID struct { D1 uint32 D2 uint16 D3 uint16 D4 [8]uint8 } // NewUUID returns a new UUID using RFC 4122 algorithm. func NewUUID() (u UUID) { u = UUID{} // Set all bits to randomly (or pseudo-randomly) chosen values. uuid := (*[16]byte)(unsafe.Pointer(&u))[:] _, err := rand.Reader.Read(uuid) if err != nil { panic("rand.Read failed") } uuid[8] = (uuid[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122) var version byte = 4 uuid[6] = (uuid[6] & 0xF) | (version << 4) // u.setVersion(4) return } // String returns an unparsed version of the generated UUID sequence. func (u UUID) String() string { return fmt.Sprintf(guidFormat, u.D1, u.D2, u.D3, u.D4[0], u.D4[1], u.D4[2], u.D4[3], u.D4[4], u.D4[5], u.D4[6], u.D4[7]) } // Implementing MarshalJSON() method for type UUID func (u UUID) MarshalJSON() ([]byte, error) { s := u.String() return json.Marshal(s) } // Implementing UnmarshalJSON() method for type UUID func (u *UUID) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } uuid, err := ParseUUID(s) if err != nil { return err } *u = uuid return nil } // ParseUUID parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f" // or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID. func ParseUUID(uuidStr string) (UUID, error) { if uuidStr[0] == '{' { uuidStr = uuidStr[1:] // Skip over the '{' } uuid := UUID{} _, err := fmt.Sscanf(uuidStr, guidFormat, &uuid.D1, &uuid.D2, &uuid.D3, &uuid.D4[0], &uuid.D4[1], &uuid.D4[2], &uuid.D4[3], &uuid.D4[4], &uuid.D4[5], &uuid.D4[6], &uuid.D4[7]) if err != nil { return UUID{}, err } return uuid, nil }