go · md5 / sha-1 / sha-256 · nsrl-scale
Hash allow/deny lookup, at NSRL scale.
Filter known-good files against an NSRL reference set, or flag known-bad hashes from a threat-intel feed — one Set interface over a fast in-memory store or a bbolt-backed store for tens of millions of entries.
MIT licensed · single dependency (bbolt) · MD5 · SHA-1 · SHA-256
set, _ := hashset.LoadTextFile("known-bad.txt") defer set.Close() if set.Contains("sha256", digest) { // flag it } fmt.Println(set.Counts()) // map[md5:… sha1:… sha256:…]
what you get
One Set interface, allow or deny.
The same store powers NSRL known-good filtering and known-bad flagging — from a one-off text list to a fifty-million-entry on-disk database.
Allow and deny in one API
The same Set backs both allowlist (NSRL known-good) and denylist (known-bad) workflows — the difference is your data, not your code.
MD5, SHA-1, SHA-256
The algorithm is auto-detected by hash length — 32, 40, or 64 hex characters — so mixed lists just work.
Two backends
A fast in-memory store (~1M entries, O(1)) or a bbolt-backed on-disk store (~50M NSRL-scale, O(log N)) — same lookups either way.
Ingests real lists
Reads plain text hash lists — with # comments and mixed algorithms — and NSRL NSRLFile.txt quoted-CSV.
Auto-detecting Open
Open(path) picks the backend straight from the file — a bbolt database or a text list — so callers don't have to choose.
Lean
A single dependency (go.etcd.io/bbolt), with progress callbacks during builds so long ingests stay observable.
usage
In-memory list, or NSRL on disk.
Load a text list straight into memory for quick lookups, or build a bbolt database once and reopen it read-only for tens of millions of entries.
// In-memory — load a text list and query set, err := hashset.LoadTextFile("known-bad.txt") if err != nil { /* ... */ } defer set.Close() if set.Contains("sha256", digest) { // flag it }
// NSRL scale — build once, then open read-only in, _ := os.Open("NSRLFile.txt") defer in.Close() _ = hashset.Build(in, "nsrl.hashset", hashset.BuildOpts{ Format: "auto", Progress: func(n int64) { log.Printf("%d hashes", n) }, }) set, _ := hashset.OpenBolt("nsrl.hashset") defer set.Close()
- LoadTextFile
- LoadText
- Build
- OpenBolt
- Open
- Contains
- Counts
install
Add it to your module.
One import and a single transitive dependency (go.etcd.io/bbolt).
go get github.com/richardwooding/go-hashset
import hashset "github.com/richardwooding/go-hashset"
Extracted from file-search-on, where it backs the known-good / known-bad search predicates. Full API on the Go Reference.