murmur3

Native Go implementation of Austin Appleby's MurmurHash3, exposing seedable 32-, 64-, and 128-bit hashers through Go's standard hash.Hash interface.

Library
Go
vv1.1.0
1,016stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
41/100Fair
Development Activity0
Maintenance20
Community56
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
58/100Fair
Architecture68
Code Quality55
Innovation72
Learning Curve35

murmur3 is a native Go port of Austin Appleby’s third MurmurHash revision (MurmurHash3), a fast, well-distributed, non-cryptographic hash function widely used for hash tables, sharding, and probabilistic data structures like Bloom filters. The package implements all three common output widths — 32-bit, 64-bit, and 128-bit — and adapts the reference algorithm’s block-mixing design to Go’s streaming hash.Hash interface so hashers can be fed data incrementally across multiple Write() calls, not just in one shot.

Each width is available both as a constructible, resettable hasher (New32, New64, New128, and their WithSeed variants) and as a single-call convenience function (Sum32, Sum64, Sum128) for the common case of hashing an in-memory byte slice. With zero external dependencies and a tiny, standard-library-only implementation, it’s a common building block underneath higher-level Go libraries that need fast, seedable, non-cryptographic hashing.

What You Get

  • 32/64/128-bit hashers - New32, New64, and New128 constructors return standard hash.Hash-compatible digests for each output width.
  • Seedable variants - New32WithSeed, New64WithSeed, and New128WithSeed initialize any hasher with an explicit uint32 seed for bucket or partition diversification.
  • One-shot Sum functions - Sum32, Sum64, and Sum128 (plus their WithSeed counterparts) compute a hash in a single call without manually wiring up a Hash object.
  • Streaming Write() support - every digest implements io.Writer via hash.Hash, so data can be fed incrementally across multiple Write calls before finalizing.

Common Use Cases

  • Hash table / sharding keys - fast, well-distributed 32- or 64-bit hashes for bucketing keys across shards or hash tables.
  • Bloom filters and probabilistic data structures - MurmurHash3’s speed and distribution quality make it a common choice for the independent hash functions a Bloom filter needs.
  • Consistent hashing / load balancing - 128-bit output gives enough entropy for ring-based consistent-hashing schemes that distribute load across nodes.
  • De-duplication and checksumming of non-cryptographic data - quick fingerprinting of byte blobs where cryptographic guarantees aren’t required.

Under The Hood

Architecture The package builds around a shared digest struct (in murmur.go) that embeds a bmixer interface (bmix, Size, reset), letting all three output widths share one block-buffering Write() implementation while each width supplies its own finalization math in murmur32.go, murmur64.go, and murmur128.go; digest64 is literally declared as type digest64 digest128 and reuses 128-bit mixing via a raw type conversion, truncating to the first 64 bits, so a change to the shared bmix block logic cascades to all three widths and the 64-bit path stays tightly coupled to 128-bit’s exact memory layout.

Tech Stack Implemented entirely with the Go standard library — hash, math/bits, and unsafe — with no third-party dependencies; it uses unsafe.Pointer to reinterpret byte slices as uint32/uint64/[2]uint64 for word-at-a-time block reads, math/bits.RotateLeft32/RotateLeft64 for the algorithm’s mixing rotations, and is built/tested with plain go build/go test under a legacy Travis CI config.

Code Quality murmur_test.go carries a fixed table of reference hash vectors across all three widths and three seeds, exercising full-buffer writes, incremental byte-by-byte streaming, Reset()-then-rewrite, and equivalence between the streaming API and the one-shot Sum functions, plus per-width benchmarks — real correctness coverage using plain t.Errorf rather than an assertion library; there’s no linter configuration, no typed errors (Write always returns a nil error), and naming stays terse (h1, k1, c1_32) as a close port of the reference C algorithm rather than idiomatic Go naming.

API Design The public surface is small and idiomatic: New32/New64/New128 return standard-library hash.Hash32/hash.Hash64 (and a custom Hash128 interface for the 128-bit case), so the package drops into any code already written against Go’s standard hashing interfaces with zero adapter code, while Sum32/Sum64/Sum128 cover the common one-shot case in a single function call. There are no dedicated example files, so discovering usage patterns beyond the README benchmarks means reading the test file directly.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search