github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/stringid/stringid.go (about) 1 // Package stringid provides helper functions for dealing with string identifiers 2 package stringid // import "github.com/demonoid81/moby/pkg/stringid" 3 4 import ( 5 "crypto/rand" 6 "encoding/hex" 7 "fmt" 8 "regexp" 9 "strconv" 10 "strings" 11 ) 12 13 const shortLen = 12 14 15 var ( 16 validShortID = regexp.MustCompile("^[a-f0-9]{12}$") 17 validHex = regexp.MustCompile(`^[a-f0-9]{64}$`) 18 ) 19 20 // IsShortID determines if an arbitrary string *looks like* a short ID. 21 func IsShortID(id string) bool { 22 return validShortID.MatchString(id) 23 } 24 25 // TruncateID returns a shorthand version of a string identifier for convenience. 26 // A collision with other shorthands is very unlikely, but possible. 27 // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller 28 // will need to use a longer prefix, or the full-length Id. 29 func TruncateID(id string) string { 30 if i := strings.IndexRune(id, ':'); i >= 0 { 31 id = id[i+1:] 32 } 33 if len(id) > shortLen { 34 id = id[:shortLen] 35 } 36 return id 37 } 38 39 // GenerateRandomID returns a unique id. 40 func GenerateRandomID() string { 41 b := make([]byte, 32) 42 for { 43 if _, err := rand.Read(b); err != nil { 44 panic(err) // This shouldn't happen 45 } 46 id := hex.EncodeToString(b) 47 // if we try to parse the truncated for as an int and we don't have 48 // an error then the value is all numeric and causes issues when 49 // used as a hostname. ref #3869 50 if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil { 51 continue 52 } 53 return id 54 } 55 } 56 57 // ValidateID checks whether an ID string is a valid image ID. 58 func ValidateID(id string) error { 59 if ok := validHex.MatchString(id); !ok { 60 return fmt.Errorf("image ID %q is invalid", id) 61 } 62 return nil 63 }