nanolab
nanolab

Reputation: 337

Modified FNV-1 hash algorithm in golang

Native library has FNV-1 hash algorithm https://golang.org/pkg/hash/fnv/ that returns uint64 value (range: 0 through 18446744073709551615). I need to store this value in PostgreSQL bigserial, but it's range is 1 to 9223372036854775807.

It is possible to change hash size to eg. 56?http://www.isthe.com/chongo/tech/comp/fnv/index.html#xor-fold

Can someone help to change native algorithm to produce 56 bit hashes? https://golang.org/src/hash/fnv/fnv.go


Update

Did it myself using this doc http://www.isthe.com/chongo/tech/comp/fnv/index.html#xor-fold

package main

import (
    "fmt"
    "hash/fnv"
)

func main() {
    const MASK uint64 = 1<<63 - 1
    h := fnv.New64()
    h.Write([]byte("1133"))
    hash := h.Sum64()
    fmt.Printf("%#x\n", MASK)
    fmt.Println(hash)
    hash = (hash >> 63) ^ (hash & MASK)
    fmt.Println(hash)
}

http://play.golang.org/p/j7q3D73qqu

Is it correct?

Upvotes: 0

Views: 1177

Answers (1)

thwd
thwd

Reputation: 24848

Is it correct?

Yes, it's a correct XOR-folding to 63 bits. But there's a much easier way:

hash = hash % 9223372036854775808

The distribution of XOR-folding is dubious, probably proven somewhere but not immediately obvious. Modulo, however, is clearly a wrapping of the hash algo's distribution to a smaller codomain.

Upvotes: 3

Related Questions