Password Generator
Math.random() must never make a password — and avoiding modulo bias is the part most people get wrong.
- JavaScript
- Web Crypto
- CSS
- HTML
About this project
A password generator with a length slider, character-set toggles, a look-alike filter, copy to clipboard, and a strength meter that reports entropy in bits with the actual number on it instead of the word "strong".
There are two separate mistakes it exists to teach, both in one small function. The first is the source: Math.random() is only required to be approximately uniform, is produced by an algorithm with a fixed amount of state, and can be recomputed by anyone who recovers that state. A password from Math.random() is not something an attacker has to guess. The second is the mapping: taking a random byte and reducing it with the modulo operator makes some characters more likely than others, and the page includes a live experiment that demonstrates the skew rather than asking you to take it on trust.
The app takes its own argument seriously. If crypto.getRandomValues is missing it disables every control and refuses to generate, because a fallback would produce a password that looks identical on the meter and is not.
What you will learn
- Know why Math.random() is unsuitable for secrets, and what makes crypto.getRandomValues() different
- Implement rejection sampling, and understand the modulo bias it removes
- Calculate password strength as entropy in bits rather than guessing at a label
- Measure the real cost of common password rules, like "at least one of each type"
- Refuse to degrade: fail loudly when the secure source is missing rather than falling back
Before you start
- JavaScript basics — arrays, functions and events
- Comfort with logarithms helps for the entropy section, but the README derives it
- A browser and a text editor. Nothing to install.
New to JavaScript? The free JavaScript course covers everything this project assumes.
Academic integrity notice
These projects are provided for learning, experimentation and reference. Understand the code, modify it for your own requirements, and acknowledge external work according to your institution’s academic policies. Priodemy does not supply work to be submitted as your own.
Features
- Every character drawn from crypto.getRandomValues() with rejection sampling, so no character is favoured
- Strength shown as entropy in bits, with the arithmetic and the alphabet size printed alongside
- A built-in experiment that measures modulo bias in the browser and charts it
- Length 8 to 64, character-set toggles, look-alike filter and an "at least one of each" rule
- The real entropy cost of that rule is calculated and subtracted, not ignored
- Refuses to run rather than silently falling back to an insecure source
Technology stack
Track: Web Development · Level: Mini project
What is included
- index.html, style.css and script.js — commented throughout
- A README on CSPRNGs, modulo bias, rejection sampling and how entropy is calculated
- Suggested extensions, including passphrase generation and two-byte widening
Delivered as a 23 KB ZIP. SHA-256 published under Changelog so you can verify it.
System requirements
- Operating system
- Any
- Runtime
- Any modern browser. No install, no build step. Works offline.
Licence
Learn from it, change it, and use it in your own coursework and personal projects. Do not resell it or pass it off as your own original work.
- Personal and educational use
- Modifying the code however you like
- Using it as the basis of your own coursework, with honest acknowledgement
- Putting your modified version in a portfolio or on your own GitHub
- Reselling or redistributing the project, modified or not
- Presenting it as your own original work
- Commercial deployment — see the Commercial licence
Support window: 6 months from download.
Frequently asked
Is Math.random() genuinely unsafe for this?
Yes. It is not specified to be unpredictable, and no engine tries to make it so. The generators in Chrome and Firefox both run on a fixed amount of internal state that can be recovered from ordinary outputs — after which every future value is known. Length does not help, because the number of possible passwords is capped by the state, not by the password.
What is modulo bias?
If you take a random byte from 0 to 255 and reduce it modulo an alphabet of 88, the first 80 characters can come from three different bytes and the rest from only two. Those characters are 50% more likely. Rejection sampling — throwing away the bytes that would cause the skew — removes it, and the page measures the difference for you.
Should I use this as my real password manager?
No. It is a teaching project, and it says so. It generates good passwords and nothing leaves the tab, but a real password manager also stores, syncs and protects them, which is a different job entirely.
Changelog
- First release
SHA-2564c002b2b7119ca71a3118ed83c2f71d521673ec260cc9ab6a662f574d27d0cc9