package repocli import ( "crypto/sha256" "crypto/sha512" "hash" "encoding/hex" "errors" "strings" ) func SHA256Digest(src []byte) string { hasher := sha256.New() hasher.Write(src) sum := hasher.Sum(nil) return "sha256:" + hex.EncodeToString(sum) } func SHA512Digest(src []byte) string { hasher := sha512.New() hasher.Write(src) sum := hasher.Sum(nil) return "sha512:" + hex.EncodeToString(sum) } type Algorithm int const ( Undefined Algorithm = iota SHA256 SHA384 SHA512 ) func DigestType(digest string) Algorithm { var err error var algorithm Algorithm digest = strings.ToLower(digest) digest = strings.TrimPrefix(digest, "sha256:") digest = strings.TrimPrefix(digest, "sha384:") digest = strings.TrimPrefix(digest, "sha512:") decoded, err := hex.DecodeString(digest) if err != nil { return Undefined } switch len(decoded) { case 32: algorithm = SHA256 case 48: algorithm = SHA384 case 64: algorithm = SHA512 default: algorithm = Undefined } return algorithm } type Digest struct { algorithm Algorithm decoded []byte } func NewDigestFromBytes(algorithm Algorithm, payload []byte) *Digest { var sum []byte var hasher hash.Hash switch algorithm { case SHA512: hasher = sha512.New() case SHA384: hasher = sha512.New384() default: hasher = sha256.New() } hasher.Write(payload) sum = hasher.Sum(nil) digest := &Digest{ algorithm: algorithm, decoded: sum, } return digest } func ParseDigest(str string) (*Digest, error) { var err error digest := &Digest{} str = strings.ToLower(str) str = strings.TrimPrefix(str, "sha256:") str = strings.TrimPrefix(str, "sha384:") str = strings.TrimPrefix(str, "sha512:") decoded, err := hex.DecodeString(str) if err != nil { err := errors.New("Can't decode digest") return digest, err } digest.decoded = decoded switch len(decoded) { case 32: digest.algorithm = SHA256 case 48: digest.algorithm = SHA384 case 64: digest.algorithm = SHA512 default: err = errors.New("Unknown digest type") return digest, err } return digest, err } func (dig *Digest) Hex() string { return hex.EncodeToString(dig.decoded) } func (dig *Digest) Algorithm() Algorithm { return dig.algorithm } func (dig *Digest) Prefix() string { var prefix string switch dig.algorithm { case SHA256: prefix = "sha256" case SHA384: prefix = "sha384" case SHA512: prefix = "sha512" } return prefix } func (dig *Digest) Encoded() string { var prefix string switch dig.algorithm { case SHA256: prefix = "sha256" case SHA384: prefix = "sha384" case SHA512: prefix = "sha512" } hexx := hex.EncodeToString(dig.decoded) return prefix + ":" + hexx }