bitwise XOR to combine hashes for set/struct fails miserably even for basic cases
ivpr opened this issue · 1 comments
ivpr commented
We are using hashstructure library in one of our projects. It is causing collisions even in basic cases. See the below example
package main
import (
"github.com/mitchellh/hashstructure"
"fmt"
)
func main() {
type Item struct {
name string
priority int
}
type BitwiseXORTest struct {
name string
items []Item `hash:"set"`
}
testCase1 := BitwiseXORTest{
"testCase",
[]Item{{"FirstItem", 1}, {"SecondItem", 2}},
}
testCase2 := BitwiseXORTest{
"testCase",
[]Item{{"SecondItem", 1}, {"FirstItem", 2}},
}
hash1, _ := hashstructure.Hash(testCase1, nil)
hash2, _ := hashstructure.Hash(testCase2, nil)
if hash1 == hash2 {
//Prints Hash Matches: 8963032841294998213 8963032841294998213
fmt.Println("Hash Matches: ", hash1, hash2)
}
}
In the above case, even if the priorities are different for both the items, hash generated is the same. This must be happening because bits touched by FNV64(priority) are not touched by FNV of other fields. XOR also fails incase of identical values
Since we have all the values in the set/struct before hand, a better approach instead of bitwise XOR would be to
- calculate the hashes of all the elements in the set/struct
- sort them
- combine them in the same way as ordered slice
This approach will solve the above mentioned problems. Thoughts?
louis77 commented
Same problem here, it seems that "set" option doesn't work for structs.