Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Different slice in struct result in the same hash #47

Open
hunghuy201280 opened this issue Jun 22, 2024 · 6 comments
Open

Different slice in struct result in the same hash #47

hunghuy201280 opened this issue Jun 22, 2024 · 6 comments

Comments

@hunghuy201280
Copy link

hunghuy201280 commented Jun 22, 2024

Here's how to reproduce it:

package main

import (
	"fmt"
	"github.com/mitchellh/hashstructure/v2"
)

type TempStruct struct {
	Strings []string `hash:"set"`
}

func main() {
	channelIds := &[]string{
		"66693f7ecdd2e6e2b6f30c18", "66693f7ecdd2e6e2b6f30c19",
	}

	structt := TempStruct{Strings: *channelIds}

	hashInt, _ := hashstructure.Hash(structt, hashstructure.FormatV2,
		&hashstructure.HashOptions{SlicesAsSets: true})
	channelIds1 := &[]string{
		"66759857b42b04c45ed0c6e6", "66759857b42b04c45ed0c6e7",
	}
	struct1 := TempStruct{Strings: *channelIds1}

	hashInt1, _ := hashstructure.Hash(struct1, hashstructure.FormatV2, nil)
	fmt.Println(hashInt)
	fmt.Print(hashInt1)
}

which will print:

4385387346745637338
4385387346745637338
@MJacred
Copy link

MJacred commented Jul 9, 2024

This fork seems to notice the difference: https://github.com/creker/hashstructure

see: https://go.dev/play/p/7NGEOYu9AZX

@MJacred
Copy link

MJacred commented Jul 9, 2024

This issue seems like a duplicate of or related to #36

and was apparently fixed in this fork: michaelbeaumont@d0db090

EDIT: tested the commit and it does NOT fix this issue

EDIT2: I'm afraid this is simply the limit of the used FNV-1 algorithm. See also here.
If you change fnv.New64() to fnv.New64a() in hashstructure.go, then the collision does not occur, simply because it's has slightly better avalanche characteristics (according to wikipedia).
The reason why creker's approach should always work is because they use sha256, which is the slowest, but also collision-free way

@hunghuy201280
Copy link
Author

Currently I need to iterate through the input slice and use sha256 to hash every element before using hashstructure.Hash, this way will prevent collision temporarily

@MJacred
Copy link

MJacred commented Jul 10, 2024

That's certainly one way.
It really depends on your needs. Maybe creker's way would also work for you and faster? Faster than sha256 would be shake128: https://pkg.go.dev/golang.org/x/crypto/sha3#ShakeSum128
But in those cases, you get an []byte with size 32 or 64, no uint64...

@lordofscripts
Copy link

Has this project been abandoned? For what I gather here the owner does not care about fixing the issues :(

@mitchellh
Copy link
Owner

Has this project been abandoned? For what I gather here the owner does not care about fixing the issues :(

I don’t. I plan on archiving this repo soon, feel free to fork! 👍 https://gist.github.com/mitchellh/90029601268e59a29e64e55bab1c5bdc

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants