mitchellh/hashstructure

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

  1. calculate the hashes of all the elements in the set/struct
  2. sort them
  3. combine them in the same way as ordered slice

This approach will solve the above mentioned problems. Thoughts?

Same problem here, it seems that "set" option doesn't work for structs.