mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
util/deephash: introduce deliberate instability (#2477)
Seed the hash upon first use with the current time. This ensures that the stability of the hash is bounded within the lifetime of one program execution. Hopefully, this prevents future bugs where someone assumes that this hash is stable. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
parent
ecac74bb65
commit
a5fb8e0731
@ -2,8 +2,11 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package deephash hashes a Go value recursively, in a predictable
|
// Package deephash hashes a Go value recursively, in a predictable order,
|
||||||
// order, without looping.
|
// without looping. The hash is only valid within the lifetime of a program.
|
||||||
|
// Users should not store the hash on disk or send it over the network.
|
||||||
|
// The hash is sufficiently strong and unique such that
|
||||||
|
// Hash(x) == Hash(y) is an appropriate replacement for x == y.
|
||||||
//
|
//
|
||||||
// This package, like most of the tailscale.com Go module, should be
|
// This package, like most of the tailscale.com Go module, should be
|
||||||
// considered Tailscale-internal; we make no API promises.
|
// considered Tailscale-internal; we make no API promises.
|
||||||
@ -20,6 +23,7 @@
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scratchSize = 128
|
const scratchSize = 128
|
||||||
@ -62,10 +66,19 @@ func (s Sum) String() string {
|
|||||||
return hex.EncodeToString(s.sum[:])
|
return hex.EncodeToString(s.sum[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
once sync.Once
|
||||||
|
seed uint64
|
||||||
|
)
|
||||||
|
|
||||||
// Hash returns the hash of v.
|
// Hash returns the hash of v.
|
||||||
func (h *hasher) Hash(v interface{}) (hash Sum) {
|
func (h *hasher) Hash(v interface{}) (hash Sum) {
|
||||||
h.bw.Flush()
|
h.bw.Flush()
|
||||||
h.h.Reset()
|
h.h.Reset()
|
||||||
|
once.Do(func() {
|
||||||
|
seed = uint64(time.Now().UnixNano())
|
||||||
|
})
|
||||||
|
h.uint(seed)
|
||||||
h.print(reflect.ValueOf(v))
|
h.print(reflect.ValueOf(v))
|
||||||
h.bw.Flush()
|
h.bw.Flush()
|
||||||
// Sum into scratch & copy out, as hash.Hash is an interface
|
// Sum into scratch & copy out, as hash.Hash is an interface
|
||||||
|
Loading…
Reference in New Issue
Block a user