- Published on
How to Hash a Struct in Go
- Authors
- Name
- Yair Mark
- @yairmark
Being able to hash a struct is useful. For example, you may want to have a map that uses a struct's hash as the key. I found a few libraries that do this but I also came across the official sha256 class. My requirements were fairly straightforward and generally, I prefer using standard libraries over external libraries if I have the option.
I looked more into using the standard library. This library looked ideal except that it had no examples of how to SHA a struct.
After a bit of searching, I came across this answer.
Based on all this I came up with the following method to sha256 a struct or anything actually:
import "crypto/sha256"
func AsSha256(o interface{}) string {
h := sha256.New()
h.Write([]byte(fmt.Sprintf("%v", o)))
return fmt.Sprintf("%x", h.Sum(nil))
}
To see how this works you can try out the below code which is also available at this play ground:
package main
import (
"crypto/sha256"
"fmt"
)
type Person struct {
Name string
Surname string
Age int
}
func asSha256(o interface{}) string {
h := sha256.New()
h.Write([]byte(fmt.Sprintf("%v", o)))
return fmt.Sprintf("%x", h.Sum(nil))
}
func main() {
person1 := Person{
Name: "John",
Surname: "Smith",
Age: 18,
}
fmt.Println("------------- Person1's hash")
fmt.Println(asSha256(person1))
person2 := Person{
Name: "John",
Surname: "Smith",
Age: 22,
}
fmt.Println("------------- Person2's hash")
fmt.Println(asSha256(person2))
}
This outputs:
------------- Person1's hash
f20fe06d96e179073fc3eebac62d7a2edf3164f0c50524d82c0c6390013bbc4a
------------- Person2's hash
acab53a42218b1ddee807fb68ecae135d1f3b046c12a4db4bf6d36fd790f6c6a
Program exited.
Some caveat's with this approach:
- It is tied to an objects
String
method.- As a result changing this will result in you getting a different hash - even something as small as adding or removing a space.
- You also need to make sure that the
String
method includes all the fields that should be SHA'd - leaving some key fields out will result in collisions.- For example if my
Person
String
method only outputAge
there would be a collision for people who are the same age.
- For example if my
- I have not tested how performant it is - you would need to do this yourself if performance is an issue for your app.