Go BKDR Hash Code Example (Online Runner)

Go BKDR hash examples with seed parsing, number/hex output, and file hashing to match the BKDR tool.

Online calculator: use the site BKDR text tool.

Calculation method

BKDRHash multiplies the rolling value by a seed and adds each byte, truncated to 32 bits.

Implementation notes

  • Package: no external dependencies; pure Go.
  • Implementation: hashes UTF-8 bytes and masks to 32 bits to match the tool.
  • Notes: BKDR is not cryptographic; keep the seed consistent across systems.

Text hashing example

go
package main

import (
	"fmt"
)

const (
	defaultSeed uint32 = 131
	uint32Mask         = 0xFFFFFFFF
)

func bkdrHashBytes(data []byte, seed uint32) uint32 {
	var value uint32
	for _, b := range data {
		value = value*seed + uint32(b)
	}
	return value & uint32Mask
}

func main() {
	value := bkdrHashBytes([]byte("hello"), defaultSeed)
	fmt.Printf("%08x\n", value)
}

File hashing example

go
package main

import (
	"fmt"
	"os"
)

const (
	defaultSeed uint32 = 131
	uint32Mask         = 0xFFFFFFFF
)

func bkdrHashBytes(data []byte, seed uint32) uint32 {
	var value uint32
	for _, b := range data {
		value = value*seed + uint32(b)
	}
	return value & uint32Mask
}

func main() {
	file, err := os.CreateTemp("", "bkdr-example-*.bin")
	if err != nil {
		panic(err)
	}
	defer os.Remove(file.Name())
	file.WriteString("hello")
	file.Close()

	data, err := os.ReadFile(file.Name())
	if err != nil {
		panic(err)
	}
	fmt.Printf("%08x\n", bkdrHashBytes(data, defaultSeed))
}

Complete script (implementation + tests)

go
package main

import (
	"fmt"
	"os"
	"strconv"
)

const (
	defaultSeed uint32 = 131
	uint32Mask         = 0xFFFFFFFF
)

type OutputFormat string

const (
	OutputNumber OutputFormat = "number"
	OutputHex    OutputFormat = "hex"
)

func parseSeed(value string) uint32 {
	if value == "" {
		return defaultSeed
	}
	parsed, err := strconv.ParseUint(value, 0, 32)
	if err != nil {
		return defaultSeed
	}
	return uint32(parsed) & uint32Mask
}

func bkdrHashBytes(data []byte, seed uint32) uint32 {
	if seed == 0 {
		panic("seed must be positive")
	}
	var value uint32
	for _, b := range data {
		value = value*seed + uint32(b)
	}
	return value & uint32Mask
}

func formatBKDR(value uint32, output OutputFormat) string {
	if output == OutputHex {
		return fmt.Sprintf("%08x", value)
	}
	return strconv.FormatUint(uint64(value), 10)
}

func bkdrText(text string, seed uint32, output OutputFormat) string {
	return formatBKDR(bkdrHashBytes([]byte(text), seed), output)
}

func bkdrFile(path string, seed uint32, output OutputFormat) string {
	data, err := os.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return formatBKDR(bkdrHashBytes(data, seed), output)
}

func main() {
	seed := parseSeed("0x83")
	fmt.Println(bkdrText("hello", seed, OutputNumber))
	fmt.Println(bkdrText("hello", seed, OutputHex))

	if got := bkdrText("", defaultSeed, OutputHex); got != "00000000" {
		panic("BKDR empty string mismatch")
	}
	if got := bkdrText("abc", defaultSeed, OutputHex); got != "001998f2" {
		panic("BKDR test vector mismatch")
	}

	fmt.Println("BKDR tests passed")
}