stringid.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Package stringid provides helper functions for dealing with string identifiers
  2. package stringid
  3. import (
  4. "crypto/rand"
  5. "encoding/hex"
  6. "io"
  7. "regexp"
  8. "strconv"
  9. "strings"
  10. "github.com/docker/docker/pkg/random"
  11. )
  12. const shortLen = 12
  13. var validShortID = regexp.MustCompile("^[a-z0-9]{12}$")
  14. // IsShortID determines if an arbitrary string *looks like* a short ID.
  15. func IsShortID(id string) bool {
  16. return validShortID.MatchString(id)
  17. }
  18. // TruncateID returns a shorthand version of a string identifier for convenience.
  19. // A collision with other shorthands is very unlikely, but possible.
  20. // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller
  21. // will need to use a longer prefix, or the full-length Id.
  22. func TruncateID(id string) string {
  23. if i := strings.IndexRune(id, ':'); i >= 0 {
  24. id = id[i+1:]
  25. }
  26. trimTo := shortLen
  27. if len(id) < shortLen {
  28. trimTo = len(id)
  29. }
  30. return id[:trimTo]
  31. }
  32. func generateID(crypto bool) string {
  33. b := make([]byte, 32)
  34. r := random.Reader
  35. if crypto {
  36. r = rand.Reader
  37. }
  38. for {
  39. if _, err := io.ReadFull(r, b); err != nil {
  40. panic(err) // This shouldn't happen
  41. }
  42. id := hex.EncodeToString(b)
  43. // if we try to parse the truncated for as an int and we don't have
  44. // an error then the value is all numeric and causes issues when
  45. // used as a hostname. ref #3869
  46. if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil {
  47. continue
  48. }
  49. return id
  50. }
  51. }
  52. // GenerateRandomID returns a unique id.
  53. func GenerateRandomID() string {
  54. return generateID(true)
  55. }
  56. // GenerateNonCryptoID generates unique id without using cryptographically
  57. // secure sources of random.
  58. // It helps you to save entropy.
  59. func GenerateNonCryptoID() string {
  60. return generateID(false)
  61. }