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  }