| package guid |
| |
| import ( |
| "crypto/rand" |
| "encoding/json" |
| "fmt" |
| "io" |
| "strconv" |
| "strings" |
| ) |
| |
| var _ = (json.Marshaler)(&GUID{}) |
| var _ = (json.Unmarshaler)(&GUID{}) |
| |
| type GUID [16]byte |
| |
| func New() GUID { |
| g := GUID{} |
| _, err := io.ReadFull(rand.Reader, g[:]) |
| if err != nil { |
| panic(err) |
| } |
| return g |
| } |
| |
| func (g GUID) String() string { |
| return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:]) |
| } |
| |
| func FromString(s string) GUID { |
| if len(s) != 36 { |
| panic(fmt.Sprintf("invalid GUID length: %d", len(s))) |
| } |
| if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { |
| panic("invalid GUID format") |
| } |
| indexOrder := [16]int{ |
| 0, 2, 4, 6, |
| 9, 11, |
| 14, 16, |
| 19, 21, |
| 24, 26, 28, 30, 32, 34, |
| } |
| byteOrder := [16]int{ |
| 3, 2, 1, 0, |
| 5, 4, |
| 7, 6, |
| 8, 9, |
| 10, 11, 12, 13, 14, 15, |
| } |
| var g GUID |
| for i, x := range indexOrder { |
| b, err := strconv.ParseInt(s[x:x+2], 16, 16) |
| if err != nil { |
| panic(err) |
| } |
| g[byteOrder[i]] = byte(b) |
| } |
| return g |
| } |
| |
| func (g GUID) MarshalJSON() ([]byte, error) { |
| return json.Marshal(g.String()) |
| } |
| |
| func (g *GUID) UnmarshalJSON(data []byte) error { |
| *g = FromString(strings.Trim(string(data), "\"")) |
| return nil |
| } |