68

For example:

hash("HelloWorld") = 1234567

Is there any built-in function could do this ?

Thanks.

zzzz
  • 87,403
  • 16
  • 175
  • 139
WoooHaaaa
  • 19,732
  • 32
  • 90
  • 138

2 Answers2

133

The hash package is helpful for this. Note it's an abstraction over specific hash implementations. Some ready made are found in the package subdirectories.

Example:

package main

import (
        "fmt"
        "hash/fnv"
)

func hash(s string) uint32 {
        h := fnv.New32a()
        h.Write([]byte(s))
        return h.Sum32()
}

func main() {
        fmt.Println(hash("HelloWorld"))
        fmt.Println(hash("HelloWorld."))
}

(Also here)


Output:

926844193
107706013
zzzz
  • 87,403
  • 16
  • 175
  • 139
  • 4
    Also, it's possible to use single instance and `Write`/`Reset`, instead of creating `New32a` every time. I don't know how much it's cost. For example: https://play.golang.org/p/aUeNBo755g – Ivan Black Aug 31 '17 at 17:58
  • 1
    Are these hashes unique? can i use it as a unique identifier? – Gokul Raj Kumar Jan 17 '19 at 08:27
  • 3
    These hashes are not very unique. The chances of two different strings matching the same uint32 are approximately 1 to 4 billion. I would not use it for uniqueness. Here is an example which may prove more useful: every task has a unique "string", and I would like to uniformly distribute the tasks between 50 queues. I would do (with the above function) hash("HelloWorld") % 50. – Tomer Jan 27 '19 at 16:04
  • This is a bad method, 797186 and 40189 has the same hash: 270439499 – iwind Apr 27 '19 at 10:07
  • 2
    @iwind Every hash function into a smaller space (like arbitrary-length string into uint32 here) is guaranteed to have collisions so "I found one specific collision" is not an argument for whether a method is good or bad. If you analyzed the method and found a high collision rate or nonuniform distribution or some other meaningful flaw that would be a compelling argument, but I imagine such analyses already exist for FNV. – Backgammon Aug 30 '19 at 19:47
  • @Backgammon ok, i agree with you. – iwind Sep 08 '19 at 01:53
  • 3
    @IvanBlack I wonder about the concurrency and race condition issues when using that same New32a instance in each call to getHash. In my mind, two simultaneous getHash function calls could interleave in a way that results in one of them Resetting the other's Write before it does a Sum call, giving a result you wouldn't want. – Adé Apr 07 '21 at 06:14
9

Here is a function you could use to generate a hash number:

// FNV32a hashes using fnv32a algorithm
func FNV32a(text string) uint32 {
    algorithm := fnv.New32a()
    algorithm.Write([]byte(text))
    return algorithm.Sum32()
}

I put together a group of those utility hash functions here: https://github.com/shomali11/util

You will find FNV32, FNV32a, FNV64, FNV64a, MD5, SHA1, SHA256 and SHA512

Adirio
  • 5,040
  • 1
  • 14
  • 26
Raed Shomali
  • 1,385
  • 15
  • 7