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  }