0

I've found that function in the golang's source code and want to know whether it's truly a perfect hash function or not. Is it the correct way to test that?


package main

import (
    "fmt"
    "strconv"
    "unsafe"
)

//go:linkname strhash runtime.strhash
func strhash(p unsafe.Pointer, h uintptr) uintptr

const seed = 666
func main() {
    m := make(map[uintptr]string)
    for i := 0; i < 1000000000; i++ {
        key := strconv.Itoa(i)
        hash := strhash(unsafe.Pointer(&key), seed)
        _, exist := m[hash]
        if exist {
            fmt.Println("collision")
            break
        }
        m[hash] = key
    }

    fmt.Println("finish")
}

  • 3
    Perfect hash functions are only defined for a given set of possible inputs (every constant-size hash function produces collisions eventually if *all* inputs are allowed, because there's an infinite amount of inputs but a finite amount of outputs). Since you haven't specified one your question cannot be answered. However, given a set of inputs computing the output for every one of them is certainly one possible way to verify that there are no collisions. – Peter Oct 09 '21 at 11:37
  • 2
    the map builtin type implements an algorithm that handles collisions, read more at https://hackernoon.com/some-insights-on-maps-in-golang-rm5v3ywh Given that this function ref is the one used for `map[string]...` https://cs.opensource.google/go/go/+/master:src/runtime/alg.go;l=166?q=strhash&ss=go%2Fgo I guess it is not collision free. Though, on a practical matter i don't understand how they formalize the proof in the math aspect of the thing. But testing it on a computer can only ever be done on a subset. Otherwise you d need infinite memory. –  Oct 09 '21 at 11:38

1 Answers1

3

As far as I know/can tell, it is not. It uses the AES instructions to create the hash. You might want to check out something like https://github.com/cespare/mph.

Gari Singh
  • 11,418
  • 2
  • 18
  • 41