github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/digest/digest.go (about)

     1  package digest
     2  
     3  import (
     4  	"crypto/sha1" // nolint
     5  	"crypto/sha256"
     6  	"fmt"
     7  	"hash"
     8  	"io"
     9  	"strings"
    10  
    11  	"golang.org/x/xerrors"
    12  )
    13  
    14  type Algorithm string
    15  
    16  func (a Algorithm) String() string {
    17  	return string(a)
    18  }
    19  
    20  // supported digest types
    21  const (
    22  	SHA1   Algorithm = "sha1"   // sha1 with hex encoding (lower case only)
    23  	SHA256 Algorithm = "sha256" // sha256 with hex encoding (lower case only)
    24  	MD5    Algorithm = "md5"    // md5 with hex encoding (lower case only)
    25  )
    26  
    27  // Digest allows simple protection of hex formatted digest strings, prefixed by their algorithm.
    28  //
    29  // The following is an example of the contents of Digest types:
    30  //
    31  //	sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc
    32  type Digest string
    33  
    34  // NewDigest returns a Digest from alg and a hash.Hash object.
    35  func NewDigest(alg Algorithm, h hash.Hash) Digest {
    36  	return Digest(fmt.Sprintf("%s:%x", alg, h.Sum(nil)))
    37  }
    38  
    39  // NewDigestFromString returns a Digest from alg and a string.
    40  func NewDigestFromString(alg Algorithm, h string) Digest {
    41  	return Digest(fmt.Sprintf("%s:%s", alg, h))
    42  }
    43  
    44  func (d Digest) Algorithm() Algorithm {
    45  	return Algorithm(d[:d.sepIndex()])
    46  }
    47  
    48  func (d Digest) Encoded() string {
    49  	return string(d[d.sepIndex()+1:])
    50  }
    51  
    52  func (d Digest) String() string {
    53  	return string(d)
    54  }
    55  
    56  func (d Digest) sepIndex() int {
    57  	i := strings.Index(string(d), ":")
    58  	if i < 0 {
    59  		i = 0
    60  	}
    61  	return i
    62  }
    63  
    64  func CalcSHA1(r io.ReadSeeker) (Digest, error) {
    65  	defer r.Seek(0, io.SeekStart)
    66  
    67  	h := sha1.New() // nolint
    68  	if _, err := io.Copy(h, r); err != nil {
    69  		return "", xerrors.Errorf("unable to calculate sha1 digest: %w", err)
    70  	}
    71  
    72  	return NewDigest(SHA1, h), nil
    73  }
    74  
    75  func CalcSHA256(r io.ReadSeeker) (Digest, error) {
    76  	defer r.Seek(0, io.SeekStart)
    77  
    78  	h := sha256.New()
    79  	if _, err := io.Copy(h, r); err != nil {
    80  		return "", xerrors.Errorf("unable to calculate sha256 digest: %w", err)
    81  	}
    82  
    83  	return NewDigest(SHA256, h), nil
    84  }