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