mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-10 09:45:08 +00:00
util/deephash: make hash type opaque
The fact that Hash returns a [sha256.Size]byte leaks details about the underlying hash implementation. This could very well be any other hashing algorithm with a possible different block size. Abstract this implementation detail away by declaring an opaque type that is comparable. While we are changing the signature of UpdateHash, rename it to just Update to reduce stutter (e.g., deephash.Update). Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
@@ -53,8 +53,17 @@ func (h *hasher) setBufioWriter(w *bufio.Writer) (old *bufio.Writer) {
|
||||
return old
|
||||
}
|
||||
|
||||
// Hash returns the raw SHA-256 (not hex) of v.
|
||||
func (h *hasher) Hash(v interface{}) (hash [sha256.Size]byte) {
|
||||
// Sum is an opaque checksum type that is comparable.
|
||||
type Sum struct {
|
||||
sum [sha256.Size]byte
|
||||
}
|
||||
|
||||
func (s Sum) String() string {
|
||||
return hex.EncodeToString(s.sum[:])
|
||||
}
|
||||
|
||||
// Hash returns the hash of v.
|
||||
func (h *hasher) Hash(v interface{}) (hash Sum) {
|
||||
h.bw.Flush()
|
||||
h.h.Reset()
|
||||
h.print(reflect.ValueOf(v))
|
||||
@@ -64,7 +73,7 @@ func (h *hasher) Hash(v interface{}) (hash [sha256.Size]byte) {
|
||||
// concrete type exported and we don't want the 'hash' result
|
||||
// parameter to escape to the heap:
|
||||
h.h.Sum(h.scratch[:0])
|
||||
copy(hash[:], h.scratch[:])
|
||||
copy(hash.sum[:], h.scratch[:])
|
||||
return
|
||||
}
|
||||
|
||||
@@ -72,8 +81,8 @@ var hasherPool = &sync.Pool{
|
||||
New: func() interface{} { return newHasher() },
|
||||
}
|
||||
|
||||
// Hash returns the raw SHA-256 hash of v.
|
||||
func Hash(v interface{}) [sha256.Size]byte {
|
||||
// Hash returns the hash of v.
|
||||
func Hash(v interface{}) Sum {
|
||||
h := hasherPool.Get().(*hasher)
|
||||
defer hasherPool.Put(h)
|
||||
for k := range h.visited {
|
||||
@@ -82,30 +91,14 @@ func Hash(v interface{}) [sha256.Size]byte {
|
||||
return h.Hash(v)
|
||||
}
|
||||
|
||||
// UpdateHash sets last to the hex-encoded hash of v and reports whether its value changed.
|
||||
func UpdateHash(last *string, v ...interface{}) (changed bool) {
|
||||
// Update sets last to the hash of v and reports whether its value changed.
|
||||
func Update(last *Sum, v ...interface{}) (changed bool) {
|
||||
sum := Hash(v)
|
||||
if sha256EqualHex(sum, *last) {
|
||||
if sum == *last {
|
||||
// unchanged.
|
||||
return false
|
||||
}
|
||||
*last = hex.EncodeToString(sum[:])
|
||||
return true
|
||||
}
|
||||
|
||||
// sha256EqualHex reports whether hx is the hex encoding of sum.
|
||||
func sha256EqualHex(sum [sha256.Size]byte, hx string) bool {
|
||||
if len(hx) != len(sum)*2 {
|
||||
return false
|
||||
}
|
||||
const hextable = "0123456789abcdef"
|
||||
j := 0
|
||||
for _, v := range sum {
|
||||
if hx[j] != hextable[v>>4] || hx[j+1] != hextable[v&0x0f] {
|
||||
return false
|
||||
}
|
||||
j += 2
|
||||
}
|
||||
*last = sum
|
||||
return true
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user