uuid.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package uuid
  2. import (
  3. "crypto/rand"
  4. "encoding/hex"
  5. "errors"
  6. )
  7. var (
  8. byteGroups = []int{8, 4, 4, 4, 12}
  9. InvalidID = errors.New("Invalid ID.")
  10. )
  11. type UUID struct {
  12. byteValue [16]byte
  13. stringValue string
  14. }
  15. func (this *UUID) String() string {
  16. return this.stringValue
  17. }
  18. func (this *UUID) Bytes() []byte {
  19. return this.byteValue[:]
  20. }
  21. func bytesToString(bytes [16]byte) string {
  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. func New() *UUID {
  33. var bytes [16]byte
  34. rand.Read(bytes[:])
  35. return &UUID{
  36. byteValue: bytes,
  37. stringValue: bytesToString(bytes),
  38. }
  39. }
  40. func ParseString(str string) (*UUID, error) {
  41. text := []byte(str)
  42. if len(text) < 32 {
  43. return nil, InvalidID
  44. }
  45. var uuid UUID
  46. uuid.stringValue = str
  47. b := uuid.byteValue[:]
  48. for _, byteGroup := range byteGroups {
  49. if text[0] == '-' {
  50. text = text[1:]
  51. }
  52. _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup])
  53. if err != nil {
  54. return nil, err
  55. }
  56. text = text[byteGroup:]
  57. b = b[byteGroup/2:]
  58. }
  59. return &uuid, nil
  60. }