π― YFG Random.org True Random Number (V2)
True random numbers without ever typing your key into the graph
- number
- float
- int
The first version of this node had one real flaw: your Random.org API key lived in a widget, which means it got baked into every workflow JSON and image metadata you saved. V2 fixes exactly that. The key never touches the graph - it's read at runtime from an environment variable or a local JSON file - and on top of that it adds the genuinely useful option to never draw the same number twice. This is the version to use.
"Random.org True Random Number (V2)" is from gonzalu/ComfyUI_YFG_Comical, a quiet one-author utility pack with little community footprint - the README and source are your docs, and they're honest. It draws a true random integer from Random.org's atmospheric-noise API and emits it as number, float, and int outputs (same value, three types) so any downstream node can take it without a converter.
Key setup (the whole install)
Two ways, either works:
# Option A: environment variable before launching ComfyUI
export RANDOM_ORG_API_KEY=YOUR_KEY_HERE
// Option B: random_org_api_key.json next to RandomOrgV2.py
{ "api_key": "YOUR_API_KEY_HERE" }
That's ComfyUI/custom_nodes/ComfyUI_YFG_Comical/random_org_api_key.json. Get the free key at https://api.random.org/dashboard. No restart needed for the JSON file - it's read on each run. The node stays fully backwards-compatible: the old V1 node remains installed as RandomOrgTrueRandomNumber_node, so old workflows keep working.
The no-repeats machinery
The interesting part is ensure_unique (on by default). Two strategies, picked automatically:
- Shuffle-bag - when the range size is β€ 200,000, it pre-shuffles every value in the range and draws through them, guaranteeing no repeat until the bag is exhausted, then reshuffles. Zero memory worries, perfect coverage.
- History-based dedup - for huge ranges it remembers recent draws instead and skips duplicates, using
history_sizeandtime_window_sec.
unique_scope = range tracks uniqueness per (min, max) pair; global shares history across all ranges. retry_limit caps the attempts before giving up. One honest caveat from the README: uniqueness is session-lifetime - restart Python and the history resets. And Random.org's free quota applies no matter what, so heavy batching can trip rate limits.
The inputs that matter
minimum/maximum (inclusive ints), and mode: random calls the API, fixed returns the minimum deterministically - handy for a cacheable/reproducible workflow. That's 90% of what you'll touch.
Installing
Pack install, once:
cd ComfyUI/custom_nodes
git clone https://github.com/gonzalu/ComfyUI_YFG_Comical
Restart ComfyUI (or search "YFG Comical" in ComfyUI Manager). Needs requests; no models.
The honest take
If you want true randomness in a seed or a lottery-pick workflow, this is a clean, well-built node - and the key-handling design is a small masterclass in doing it right. The shuffle-bag is the feature that makes it worth reaching for over V1 or over random.randint. Just respect the quota, and remember "true random" means you can't reproduce a run by re-seeding - which is the point, but worth saying out loud.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| minimum | FLOAT | 0.00-9223372036854776000β9223372036854776000 | Lower bound (inclusive). Floats are converted to integers via int(). |
| maximum | FLOAT | 10.00-9223372036854776000β9223372036854776000 | Upper bound (inclusive). Floats are converted to integers via int(). |
| mode | COMBO | random | random: call random.org. fixed: return minimum deterministically (cacheable). |
| ensure_uniqueopt | BOOLEAN | true | If true, avoids repeats using shuffle-bag (preferred) or history de-dup (fallback). |
| unique_scopeopt | COMBO | range | range: uniqueness tracked per (minimum,maximum). global: shared across all ranges. |
| history_sizeopt | INT | 1001β100000 | Used by history-based de-dup (and as extra guard when global scope is enabled). |
| time_window_secopt | INT | 00β86400 | If >0, values older than this many seconds are forgotten for de-dup checks. |
| retry_limitopt | INT | 200β1000 | How many times to try finding a non-duplicate when using history-based de-dup (or global checks). |
| use_shuffle_bagopt | BOOLEAN | true | If true and range size <= 200,000, use shuffle-bag. Otherwise fall back. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| number | NUMBER | ComfyUI NUMBER output (typically behaves like a float). |
| float | FLOAT | Same value as a Python float. |
| int | INT | Same value as a Python int. |