* Add hasher interface and fnv + sha256 implemenations * update * remove * fix test * update * remove * remove * fix spelling
55 lines
2.2 KiB
Go
55 lines
2.2 KiB
Go
// Package hasher provides a generic interface and base implementation for hashing data.
|
|
package hasher
|
|
|
|
import (
|
|
"fmt"
|
|
"hash"
|
|
)
|
|
|
|
// Hasher defines a generic interface for hashing data.
|
|
// Implementations of this interface may choose to be safe for concurrent use,
|
|
// but it is not a requirement. Users should check the documentation of specific
|
|
// implementations for concurrent safety guarantees.
|
|
type Hasher interface {
|
|
// Hash takes input data and returns the hashed result.
|
|
// It returns an error if the input data is too large.
|
|
// The function is idempotent - calling it multiple times with the same input
|
|
// will produce the same output, assuming the underlying hash function is deterministic.
|
|
Hash(data []byte) ([]byte, error)
|
|
}
|
|
|
|
// baseHasher provides a base implementation for the Hasher interface.
|
|
// It uses the hash.Hash interface from the standard library to perform the actual hashing.
|
|
// This implementation is not safe for concurrent use. Each goroutine/worker should
|
|
// use its own instance of baseHasher for concurrent operations.
|
|
// Implementations that require concurrent access should wrap baseHasher with a mutex. (e.g., MutexHasher)
|
|
type baseHasher struct{ hash hash.Hash }
|
|
|
|
// InputTooLargeError is returned when the input data exceeds the maximum allowed size.
|
|
type InputTooLargeError struct {
|
|
inputSize int
|
|
maxSize int
|
|
}
|
|
|
|
func (e *InputTooLargeError) Error() string {
|
|
return fmt.Sprintf("input data exceeds the maximum allowed size: %d > %d", e.inputSize, e.maxSize)
|
|
}
|
|
|
|
const maxInputSize = 1 << 14 // 16KB
|
|
|
|
// Hash computes the hash of the given data.
|
|
// It returns an InputTooLargeError if the input data exceeds the maximum allowed size.
|
|
// This method resets the underlying hash before each computation to ensure
|
|
// that previous hashing operations do not affect the result.
|
|
func (b *baseHasher) Hash(data []byte) ([]byte, error) {
|
|
if len(data) > maxInputSize {
|
|
return nil, &InputTooLargeError{inputSize: len(data), maxSize: maxInputSize}
|
|
}
|
|
b.hash.Reset()
|
|
// nolint:errcheck
|
|
// The hash.Hash interface does not return errors on Write.
|
|
// (https://cs.opensource.google/go/go/+/refs/tags/go1.23.1:src/hash/hash.go;l=27-28)
|
|
_, _ = b.hash.Write(data)
|
|
return b.hash.Sum(nil), nil
|
|
}
|