diff --git a/ahash/ahash.go b/ahash/ahash.go index 30562c4..c666db3 100644 --- a/ahash/ahash.go +++ b/ahash/ahash.go @@ -1,5 +1,6 @@ // Package ahash provides support for hashing data with a selectable -// hash function. +// +// hash function. package ahash import ( @@ -213,6 +214,17 @@ func SumReader(algo string, r io.Reader) ([]byte, error) { return h.Sum(nil), nil } +// SumLimitedReader reads n bytes of data from the io.reader and returns the +// digest (not the hex digest) from the specified algorithm. +func SumLimitedReader(algo string, r io.Reader, n int64) ([]byte, error) { + limit := &io.LimitedReader{ + R: r, + N: n, + } + + return SumReader(algo, limit) +} + var insecureHashList, secureHashList, hashList []string func init() { diff --git a/ahash/ahash_test.go b/ahash/ahash_test.go index 0c9cd26..45ee7e7 100644 --- a/ahash/ahash_test.go +++ b/ahash/ahash_test.go @@ -139,3 +139,19 @@ func TestListLengthSanity(t *testing.T) { assert.BoolT(t, len(all) == len(secure)+len(insecure)) } + +func TestSumLimitedReader(t *testing.T) { + data := bytes.NewBufferString("hello, world") + dataLen := data.Len() + extendedData := bytes.NewBufferString("hello, world! this is an extended message") + expected := "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" + + hash, err := SumReader("sha256", data) + assert.NoErrorT(t, err) + assert.BoolT(t, fmt.Sprintf("%x", hash) == expected, fmt.Sprintf("have hash %x, want %s", hash, expected)) + + extendedHash, err := SumLimitedReader("sha256", extendedData, int64(dataLen)) + assert.NoErrorT(t, err) + + assert.BoolT(t, bytes.Equal(hash, extendedHash), fmt.Sprintf("have hash %x, want %x", extendedHash, hash)) +}