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