True Random Number Generation With Radioactive Decay
A man, a plan, a canal, americium
Creating a True Random Number Generator Using a Geiger Counter
I purchased a cheap Geiger counter a while back, mainly out of curiosity to measure radiation from some vintage lenses in my collection.
These old lenses often contain small amounts of thorium, and some of them are wildly radioactive.
While playing around with it, I started using the device to measure background radiation in my room. The Geiger counter emits random clicks when it detects an alpha particle, and as I sat there listening to the irregular rhythm, an idea struck me: this randomness could be used to create a true Random Number Generator (RNG).
Nature's Unpredictability: Alpha Decay and Randomness
The rare intersection of software, hardware, and nature is something I've been interested in ever since reading about Cloudflare's famous lava lamp wall, which uses the unpredictable movement of lava lamps to generate random numbers.
While we know the half-life of radioactive isotopes (how long it takes for half of the material to decay), predicting the exact moment when an alpha particle is emitted is impossible.
Each decay event happens randomly. The unpredictability of this process makes it an ideal source for generating random numbers.
Plugging in the Geiger Counter
Thankfully, the Geiger counter can connect to a computer via USB, allowing direct access to the output. The device records a click, or a pulse, each time an alpha particle is detected.
I could record each pulse, calculate the the time between each pulse, calculate the time difference between each pulse pair, and use that timing data to generate random bits.
How this works:
- Pulse comes in, we record that time. (Pulse1)
- Second pulse comes in, we record that time. (Pulse2)
- Since we have a previous recorded time (Pulse1), we calculate the time difference between the current pulse time and previous pulse time (P2 - P1).
- That calculation gets recorded as the time difference (Diff1).
- Repeat steps 1-4 until we have a second time difference (Diff2).
- Once we have two time differences, we compare them.
- If (Diff2 > Diff1) we record the bit as 1. If (Diff2 < Diff1) the bit is recorded as 0.
- Repeat steps 1-7 to get more bits
To visualize this better, I converted it to JavaScript and made it into a React component to display in this site. Here is an interactive example.
The lines represent the timestamp of pulses.
The circles represent time differences between pulse pairs
The bit represents... the bit.
Try clicking the "Send Pulse" button at varying speeds.
Testing for Randomness
Ensuring that a Random Number Generator is truly random is crucial, especially for applications like cryptography, simulations, and scientific research, where predictability can undermine the system's security or reliability.
There are multiple ways to test for randomness, including statistical methods like frequency analysis, autocorrelation, and more advanced tests like the Diehard tests or NIST Statistical Test Suite.
These tests check for patterns, uniform distribution, and the independence of generated bits.
Here are a couple of resources to explore more about testing randomness:
Quick test
After letting it run for a while to collect enough bits, you can do a quick check just to validate your data before getting into any more complicated tests.
Here we're chunking our bits into groups of 4 bits. Then we're converting these groups of 4 bits into a number, and counting each occurence of each number.
Stick that data in a chart and you should get close enough to an even distribution.
Background noise
This is not exactly a novel approach. The concept of using a Geiger counter to random numbers has been explored deeply.
This is just a basic example, but it can easily be expanded into more complex projects.