diff --git a/internal/deephash/deephash.go b/internal/deephash/deephash.go index e969e02b7..b33531873 100644 --- a/internal/deephash/deephash.go +++ b/internal/deephash/deephash.go @@ -24,8 +24,12 @@ func calcHash(v interface{}) string { printTo(b, v, scratch) b.Flush() scratch = h.Sum(scratch[:0]) - hex.Encode(scratch[:cap(scratch)], scratch[:sha256.Size]) - return string(scratch[:sha256.Size*2]) + // The first sha256.Size bytes contain the hash. + // Hex-encode that into the next sha256.Size*2 bytes. + src := scratch[:sha256.Size] + dst := scratch[sha256.Size:cap(scratch)] + n := hex.Encode(dst, src) + return string(dst[:n]) } // UpdateHash sets last to the hash of v and reports whether its value changed. diff --git a/internal/deephash/deephash_test.go b/internal/deephash/deephash_test.go index 047bc67dc..5b5e9a24c 100644 --- a/internal/deephash/deephash_test.go +++ b/internal/deephash/deephash_test.go @@ -134,3 +134,14 @@ func BenchmarkHashMapAcyclic(b *testing.B) { } } } + +func TestExhaustive(t *testing.T) { + seen := make(map[string]bool) + for i := 0; i < 100000; i++ { + s := calcHash(i) + if seen[s] { + t.Fatalf("hash collision %v", i) + } + seen[s] = true + } +}