id.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package user
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "errors"
  6. "github.com/v2ray/v2ray-core/common/log"
  7. )
  8. const (
  9. IDBytesLen = 16
  10. )
  11. var (
  12. InvalidID = errors.New("Invalid ID.")
  13. )
  14. // The ID of en entity, in the form of an UUID.
  15. type ID struct {
  16. String string
  17. Bytes [IDBytesLen]byte
  18. cmdKey [IDBytesLen]byte
  19. }
  20. func NewID(id string) (ID, error) {
  21. idBytes, err := UUIDToID(id)
  22. if err != nil {
  23. log.Error("Failed to parse id %s", id)
  24. return ID{}, InvalidID
  25. }
  26. md5hash := md5.New()
  27. md5hash.Write(idBytes[:])
  28. md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
  29. cmdKey := md5.Sum(nil)
  30. return ID{
  31. String: id,
  32. Bytes: idBytes,
  33. cmdKey: cmdKey,
  34. }, nil
  35. }
  36. func (v ID) CmdKey() []byte {
  37. return v.cmdKey[:]
  38. }
  39. var byteGroups = []int{8, 4, 4, 4, 12}
  40. // TODO: leverage a full functional UUID library
  41. func UUIDToID(uuid string) (v [IDBytesLen]byte, err error) {
  42. text := []byte(uuid)
  43. if len(text) < 32 {
  44. log.Error("uuid: invalid UUID string: %s", text)
  45. err = InvalidID
  46. return
  47. }
  48. b := v[:]
  49. for _, byteGroup := range byteGroups {
  50. if text[0] == '-' {
  51. text = text[1:]
  52. }
  53. _, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
  54. if err != nil {
  55. return
  56. }
  57. text = text[byteGroup:]
  58. b = b[byteGroup/2:]
  59. }
  60. return
  61. }