A random question generator can be built in a single browser tab by drawing one Uint32 from Crypto.getRandomValues and mapping each accepted value to a binary outcome, and the Yes or No Generator on Lizely implements exactly this pipeline with no Math.random fallback. The tool pulls randomness only from the browser's Web Cryptography implementation, fills a one-element Uint32Array, and translates each accepted integer into either Yes or No using even/odd parity. Because two divides 2^32 exactly, every valid Uint32 source value from 0 to 4,294,967,295 is accepted, half the range maps to Yes and half to No, and rejection sampling is reserved for non-binary outcome counts. The question you type is treated as a local label only and never feeds the random source. This article explains what a fair random question generator has to do, why Web Crypto is the right ingredient, and how to assemble one step by step using the Lizely tool as a concrete reference.

What counts as a random question generator
A random question generator, in the strict sense most people search for, is a small piece of software that accepts a question and returns a uniformly distributed answer drawn from a clearly defined set of outcomes. The simplest form returns one of two outcomes: Yes or No. More elaborate versions pick a question from a curated list and then assign a value, but both shapes share the same core contract: the question is treated as input, the answer is treated as output, and the mechanism that picks the answer must not be tunable by the user in a way that biases the result.
The distinction matters because the word "random" gets attached to many tools that are not actually uniform. A spinner with uneven sectors, a script that calls Math.random without bounding the output, or a list picker that loops through items in deterministic order can all claim randomness while producing a tilted distribution. A genuinely fair generator has three properties: a source of unpredictable bits, a mapping function that divides the source range into equally sized buckets, and a transparent disclosure of what the source actually is.
Three requirements for a fair generator
Before you assemble anything, lock down these three requirements so the final tool is honest about what it produces.
- An unpredictable source. Crypto.getRandomValues, defined in the W3C Web Cryptography specification and documented independently on MDN, fills a typed array in place with values drawn from the browser's cryptographic generator. Math.random is not suitable for fairness claims because it is not specified to be unbiased across all platforms.
- An unbiased finite-range mapping. For N outcomes, the largest multiple of N that fits inside the 2^32 source range is calculated, values at or above that multiple are rejected, and accepted values are mapped with modulo N. This rejection sampling guarantees that lower-index outcomes do not receive an extra source value when the range does not divide evenly.
- Visible methodology and explicit failure. The generator should say what source it uses, what mapping it uses, and what happens when the source fails. Silent substitution with a weaker source is worse than an outright error.
Those three points are the floor. Anything that omits one of them is producing answers that look random but cannot be defended as such.
How to create a random question generator step by step
The fastest way to ship a working random question generator today is to use the Yes or No Generator, which already implements the three requirements above in a single browser tab. The following steps mirror the verified operating steps of the tool and produce an unbiased 50/50 answer with full transparency about the source.
- Optionally enter a low-stakes question. The question field accepts up to 1,000 UTF-16 code units. The exact boundary is accepted and one code unit beyond it fails without truncation or generation. Empty text is valid because the question is optional. The question text is stored locally with the generated entry exactly as entered; trimming is only used to decide whether the history label should read No question.
- Generate a Yes or No using browser Web Crypto. Click Generate Yes or No. The tool fills a one-element Uint32Array with a fresh integer from 0 to 4,294,967,295, computes the acceptance limit for two outcomes (which equals 2^32, so every valid Uint32 is accepted), maps even values to Yes and odd values to No, and displays the result.
- Review the current answer and the newest-first history. Editing a question clears the prominently displayed current answer and any prior error so an answer associated with older wording is not mislabeled. Editing does not remove existing history entries.
- Clear history when finished. The newest-first history is capped at 20 entries. After the twenty-first generation the oldest entry is removed and a cumulative message reports exactly how many earlier answers have been discarded. Clearing history resets both the visible entries and the discarded count and also removes the current answer.
If Web Crypto is missing, blocked, or throws, the tool reports a clear failure and produces no answer. It deliberately does not fall back to Math.random because silently changing the random source would contradict the displayed methodology and make failure harder to detect.
Inside the Web Crypto mapping
The mapping is the part that turns unpredictable bits into a usable answer, and it is worth seeing once so you can judge any other generator against it.
Start with a source range of 2^32 = 4,294,967,296 distinct Uint32 values. For two outcomes, the largest multiple of 2 that fits inside that range is 2^32 itself, so the acceptance limit is the full range and no value is rejected. Even values map to Yes and odd values map to No, which assigns exactly 2^31 = 2,147,483,648 source values to each outcome.
| Quantity | Value |
|---|---|
| Source range (2^32) | 4,294,967,296 |
| Outcomes | 2 |
| Largest multiple of 2 inside 2^32 | 4,294,967,296 |
| Rejection threshold | None (full range accepted) |
| Source values mapped to Yes | 2,147,483,648 |
| Source values mapped to No | 2,147,483,648 |
That table is the worked numeric example. Two divides 2^32 evenly, so each outcome gets half the source range. With three outcomes the largest multiple would be 4,294,967,295, which equals 1,431,655,765 × 3 and is 1 less than 2^32, and the single value 4,294,967,295 would be rejected. That single rejected value is what would give the lower-index outcomes a slightly higher weight without rejection sampling, which is why the rejection path exists at all.
The same mapper is exercised at a three-outcome boundary in deterministic tests to confirm the rejection path stays correct without claiming a retry occurs during ordinary binary use. A bounded 128-draw loop caps retries so a broken injected or platform source cannot hang the tab, and deterministic test injection covers zero, one, middle values, the maximum even value, the maximum Uint32, the last accepted three-outcome value, the first rejected value followed by an accepted value, invalid source numbers, the exact 2^32 outcome-count boundary, and exactly 128 rejected draws before exhaustion.
Local data, history cap, and transparency
A fair generator is only as useful as the limits it discloses. The Yes or No Generator keeps everything in the current tab. The question, the answers, and the 20-entry history are never uploaded to Lizely and are not written to an account or remote service. No dependency, network call, account, Clipboard API, file, or ObjectURL is required to operate it.
History is the only persistence layer, and it is bounded. After the twenty-first generation the oldest entry is removed and a message reports exactly how many earlier answers have been discarded, so the cap is not a silent loss. Clearing history resets both the visible entries and the discarded count and also removes the current answer. The monotonically increasing local entry identifier prevents duplicate runtime keys and is not random data or a persistent identifier.
Random input comes only from Crypto.getRandomValues, which the W3C Web Cryptography specification defines and MDN documents for browser behavior. NIST SP 800-90A Rev. 1 supplies the broader random-bit generator context. Those sources cover the random input mechanism; the rejection mapping above is implemented and tested locally rather than borrowed from any specification.
When a random question generator is the wrong tool
Web Crypto quality does not make the question appropriate, validate the available choices, understand consequences, or provide professional judgment. A mathematically balanced answer can still be unsuitable, unlucky, or harmful when used outside casual low-stakes situations. The tool is a lightweight prompt, not advice or a decision authority.
Avoid the tool for medical, legal, financial, safety-critical, emergency, security, consent, employment, eligibility, compliance, or other high-stakes decisions. The tool does not learn preferences, weight alternatives, guarantee alternating results, prevent streaks, prove fairness over a small sample, or predict future events. Independent 50/50 results can naturally form streaks of repeated Yes or repeated No answers, and the recent history is descriptive only and never modifies probability to compensate for a streak.
If the decision carries real consequences, use a structured decision process instead: list the alternatives, score them against criteria that matter to you, and pick deliberately. A random prompt is most useful when the decision is genuinely low-stakes and the act of deciding is more effort than the decision itself.
Related reading: A Random Avatar Generator Alternative That Stays Local.