Hash Phrase
Turn any ComfyUI string into a readable, repeatable phrase
- phrase
The one-line pitch
The name is half a lie. Hash Phrase doesn't call any API, needs no key, and never touches your GPU. Feed it any string - a seed, a filename, a chunk of your prompt - and it hands back a short English phrase like document flatness backyard ruckus. Same string in, same phrase out, every single run. That's the whole job, and it does it with zero randomness.
You reach for this when ComfyUI's default identifiers feel like noise and you want something a human can actually read. Long numeric seeds, opaque hashes in output filenames, batch IDs you can't tell apart - a phrase is friendlier than a 19-digit integer, and because the mapping is deterministic it doubles as a reproducible label. Wire its output into a filename template or another text node and "which run is this?" stops being a guessing game. It's a solve-a-real-annoyance node, not a hype node. If the annoyance never hits you, you don't need it, and that's fine.
How it works
Deliberately deterministic. The node hashes your input with SHA-256, prefixed by a versioned "domain" string (ComfyUI-HashPhrase-v1\0), so a future version of the mapping can change its algorithm without breaking phrases produced today. The digest becomes a big integer, and that integer picks words - without replacement - from the EFF long Diceware wordlist, the same 7,776-word list people use to build passphrases. Words never repeat inside a phrase, which is why 16 is the ceiling rather than a typo. Empty and Unicode strings work; non-text input gets coerced to a string first. The whole conversion lives in a small pure-Python core module, so it's trivially testable and stable.
Two honest caveats, straight from the README. It's not collision-resistant and it's not a secret - don't use it for tokens or anything that needs to hide. And despite the "hash" in the name, the result doesn't depend on ComfyUI's workflow seed at all: change the KSampler seed and the phrase stays put. That's a feature when you're using it as an ID, and it's exactly the trap this node avoids.
The inputs that matter
- text - the string being converted. A multiline box; whatever goes in defines the phrase. This is also the socket you'd convert to an input and wire a dynamic value into.
- word_count - how many words come out, clamped to 1–16 with a default of 2. The number widget has increment/decrement controls.
- separator - what sits between words. Defaults to a single space; both the UI and the backend cap it at 32 characters, so the worst case is silent truncation, not a crash.
The single phrase output is a STRING, and it plugs into any STRING input - a text encode node, a filename builder, another text utility. Think of it as a value node in the classic ComfyUI plumbing sense: one authoritative string you can fan out to several sockets. There's also a quiet compatibility feature under the hood: the pack registers itself as a replacement for the older HashPhrase node, so existing workflows that used the earlier community node get migrated with their text intact (and a 4-word default) instead of erroring out.
Installing it
ComfyUI Manager is the easy path: open it, search for Hash Phrase, install, restart. Git works too:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/TensorClay/ComfyUI-HashPhrase.git
pip install -r requirements.txt
Restart, then find Hash Phrase under utils/text. Two things worth knowing up front. First, it requires ComfyUI 0.28.0 or newer - this is written against ComfyUI's newer V3 node-authoring API (no NODE_CLASS_MAPPINGS, just io.ComfyNode and an extension entrypoint), so on an older install it simply won't appear. Second, the only dependency is diceware==1.0.1, a tiny pure-Python package pinned so results stay reproducible. No torch, no model downloads, nothing heavy. If you cloned by hand and skipped the pip install, you'll hit a "Could not locate Diceware wordlist 'en_eff'" error - that's the missing package, and it's basically the entire troubleshooting story. If you cloned via a pack that doesn't install requirements automatically, same fix: install the dependency and restart.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| word_count | INT | 21–16 | Number of words (1–16). |
| separator | STRING | Text inserted between words; limited to 32 characters. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| phrase | STRING | — |