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  }