feat: initial goget release — modern IPv6-first download utility
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
//go:build linux || freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/crypto/blake2b"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// ChecksumType defines the checksum type
|
||||
type ChecksumType string
|
||||
|
||||
const (
|
||||
SHA256 ChecksumType = "sha256"
|
||||
SHA512 ChecksumType = "sha512"
|
||||
BLAKE2b ChecksumType = "blake2b"
|
||||
SHA3_256 ChecksumType = "sha3-256"
|
||||
SHA3_512 ChecksumType = "sha3-512"
|
||||
MD5 ChecksumType = "md5"
|
||||
)
|
||||
|
||||
// ChecksumVerifier verifies a file checksum
|
||||
type ChecksumVerifier struct {
|
||||
hashType ChecksumType
|
||||
hasher hash.Hash
|
||||
expected string
|
||||
}
|
||||
|
||||
// NewChecksumVerifier creates new verifier
|
||||
func NewChecksumVerifier(hashType ChecksumType, expected string) (*ChecksumVerifier, error) {
|
||||
var hasher hash.Hash
|
||||
|
||||
switch hashType {
|
||||
case SHA256:
|
||||
hasher = sha256.New()
|
||||
case SHA512:
|
||||
hasher = sha512.New()
|
||||
case BLAKE2b:
|
||||
h, err := blake2b.New256(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create blake2b hasher: %w", err)
|
||||
}
|
||||
hasher = h
|
||||
case SHA3_256:
|
||||
hasher = sha3.New256()
|
||||
case SHA3_512:
|
||||
hasher = sha3.New512()
|
||||
case MD5:
|
||||
return nil, fmt.Errorf("md5 is deprecated and not supported")
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported hash type: %s", hashType)
|
||||
}
|
||||
|
||||
return &ChecksumVerifier{
|
||||
hashType: hashType,
|
||||
hasher: hasher,
|
||||
expected: expected,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VerifyFile verifies the checksum of a file
|
||||
func (cv *ChecksumVerifier) VerifyFile(path string) (bool, string, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return false, "", fmt.Errorf("failed to open file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
cv.hasher.Reset()
|
||||
_, err = io.Copy(cv.hasher, file)
|
||||
if err != nil {
|
||||
return false, "", fmt.Errorf("failed to read file: %w", err)
|
||||
}
|
||||
|
||||
actual := hex.EncodeToString(cv.hasher.Sum(nil))
|
||||
match := actual == cv.expected
|
||||
|
||||
return match, actual, nil
|
||||
}
|
||||
|
||||
// VerifyReader verifies checksum from a reader (streaming)
|
||||
func (cv *ChecksumVerifier) VerifyReader(r io.Reader) (string, error) {
|
||||
cv.hasher.Reset()
|
||||
_, err := io.Copy(cv.hasher, r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(cv.hasher.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// Hasher returns the underlying hasher for streaming verification
|
||||
func (cv *ChecksumVerifier) Hasher() hash.Hash {
|
||||
return cv.hasher
|
||||
}
|
||||
|
||||
// Expected returns the expected checksum
|
||||
func (cv *ChecksumVerifier) Expected() string {
|
||||
return cv.expected
|
||||
}
|
||||
|
||||
// Type returns the hash function type
|
||||
func (cv *ChecksumVerifier) Type() ChecksumType {
|
||||
return cv.hashType
|
||||
}
|
||||
|
||||
// ComputeFileChecksum calculates the checksum of a file
|
||||
func ComputeFileChecksum(path string, hashType ChecksumType) (string, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var hasher hash.Hash
|
||||
switch hashType {
|
||||
case SHA256:
|
||||
hasher = sha256.New()
|
||||
case SHA512:
|
||||
hasher = sha512.New()
|
||||
case BLAKE2b:
|
||||
h, err := blake2b.New256(nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create blake2b hasher: %w", err)
|
||||
}
|
||||
hasher = h
|
||||
case SHA3_256:
|
||||
hasher = sha3.New256()
|
||||
case SHA3_512:
|
||||
hasher = sha3.New512()
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported hash type: %s", hashType)
|
||||
}
|
||||
|
||||
_, err = io.Copy(hasher, file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(hasher.Sum(nil)), nil
|
||||
}
|
||||
Reference in New Issue
Block a user