2018-07-04 10:51:47 +00:00
package multihash
import (
"errors"
"fmt"
2021-06-28 06:53:50 +00:00
mhreg "github.com/multiformats/go-multihash/core"
2018-07-04 10:51:47 +00:00
)
// ErrSumNotSupported is returned when the Sum function code is not implemented
2021-06-28 06:53:50 +00:00
var ErrSumNotSupported = mhreg . ErrSumNotSupported
2018-07-04 10:51:47 +00:00
2021-06-16 20:19:45 +00:00
var ErrLenTooLarge = errors . New ( "requested length was too large for digest" )
2018-07-04 10:51:47 +00:00
// Sum obtains the cryptographic sum of a given buffer. The length parameter
// indicates the length of the resulting digest and passing a negative value
// use default length values for the selected hash function.
func Sum ( data [ ] byte , code uint64 , length int ) ( Multihash , error ) {
2021-06-28 06:53:50 +00:00
// Get the algorithm.
hasher , err := GetHasher ( code )
2018-07-04 10:51:47 +00:00
if err != nil {
2019-06-09 07:24:20 +00:00
return nil , err
2018-07-04 10:51:47 +00:00
}
2021-06-28 06:53:50 +00:00
// Feed data in.
hasher . Write ( data )
2018-07-04 10:51:47 +00:00
2021-06-28 06:53:50 +00:00
// Compute final hash.
// A new slice is allocated. FUTURE: see other comment below about allocation, and review together with this line to try to improve.
sum := hasher . Sum ( nil )
2018-07-04 10:51:47 +00:00
2021-06-28 06:53:50 +00:00
// Deal with any truncation.
// Unless it's an identity multihash. Those have different rules.
if length < 0 {
length = hasher . Size ( )
2019-06-09 07:24:20 +00:00
}
2021-06-28 06:53:50 +00:00
if len ( sum ) < length {
return nil , ErrLenTooLarge
2019-06-09 07:24:20 +00:00
}
2021-06-28 06:53:50 +00:00
if length >= 0 {
if code == IDENTITY {
if length != len ( sum ) {
return nil , fmt . Errorf ( "the length of the identity hash (%d) must be equal to the length of the data (%d)" , length , len ( sum ) )
}
}
sum = sum [ : length ]
2019-06-09 07:24:20 +00:00
}
2021-06-28 06:53:50 +00:00
// Put the multihash metainfo bytes at the front of the buffer.
// FUTURE: try to improve allocations here. Encode does several which are probably avoidable, but it's the shape of the Encode method arguments that forces this.
return Encode ( sum , code )
2018-07-04 10:51:47 +00:00
}