Drop in a WAV recording of noise. This page walks the bytes through hashing and rejection sampling, and shows you the arithmetic at each step. Everything runs in your browser. The audio never leaves this tab.
A 16-bit PCM WAV file. Microphone hiss, rain, a detuned radio. Longer is better, but the honest limit is discussed at the bottom of this page.
Recorded noise is never uniform. Samples cluster near zero, neighbouring samples correlate, and the high byte of each sample sits at 0x00 or 0xFF almost always. Hashing spreads whatever unpredictability exists across all 64 output bytes evenly. We append a counter, SHA-512(pcm ‖ n), to draw as many blocks as we need.
Entropy is measured in bits per byte. The theoretical maximum is 8.000. Raw audio typically lands far below it; the hashed pool should sit within a rounding error of the ceiling.
A byte holds 256 values. Our alphabet holds 94 printable characters. 256 does not divide by 94, it goes twice with 68 left over. So if we simply took byte % 94, the first 68 characters would get three chances at being picked while the other 26 get only two. Those characters become roughly 50% more likely. The bias is small, real, and entirely avoidable.
The fix is to throw bytes away. The largest multiple of 94 below 256 is 188. Bytes 0 to 187 divide into exactly two clean passes over the alphabet, so they are safe. Bytes 188 to 255 are discarded and a fresh byte is drawn. We waste about 26.6% of the pool and every character becomes equally likely.
Twelve characters each, drawn from 94 possibilities. That is — bits of entropy per password, assuming the source noise carried at least that much.
Where this method stops working, and what to reach for instead.
crypto.getRandomValues(). It draws from the operating system's entropy pool, which is continuously reseeded from hardware sources that were designed for the job. That is the button above marked Synthesise noise, and it is the only source on this page whose unpredictability is worth trusting.