uuid.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 []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 []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. bytes := make([]byte, 16)
  34. rand.Read(bytes)
  35. uuid, _ := ParseBytes(bytes)
  36. return uuid
  37. }
  38. func ParseBytes(bytes []byte) (*UUID, error) {
  39. if len(bytes) != 16 {
  40. return nil, InvalidID
  41. }
  42. return &UUID{
  43. byteValue: bytes,
  44. stringValue: bytesToString(bytes),
  45. }, nil
  46. }
  47. func ParseString(str string) (*UUID, error) {
  48. text := []byte(str)
  49. if len(text) < 32 {
  50. return nil, InvalidID
  51. }
  52. uuid := &UUID{
  53. byteValue: make([]byte, 16),
  54. stringValue: str,
  55. }
  56. b := uuid.byteValue[:]
  57. for _, byteGroup := range byteGroups {
  58. if text[0] == '-' {
  59. text = text[1:]
  60. }
  61. _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup])
  62. if err != nil {
  63. return nil, err
  64. }
  65. text = text[byteGroup:]
  66. b = b[byteGroup/2:]
  67. }
  68. return uuid, nil
  69. }