Arduino True Random Number Generator

This is just a fun project I have been working on in the last little while. If you like this instructable, consider voting for it in the Arduino Challenge!

Anyone who has experience with programming will have probably used random numbers in their code. These random numbers aren't actually random though. They are actually generated using an algorithm that produces numbers that appear to be random, but the numbers actually follow a sequence. While these "pseudo-random" numbers are fine for some purposes, they just won't do for others. Cryptography is a case where the predictability of pseudo-random would allow someone to break codes with ease.

True random numbers on the other hand rely on quantum phenomena, or chaotic systems. Quantum systems include things like radioactive decay, and shot noise in electronic circuits, and are fundamentally random processes. Chaotic systems are things like atmospheric noise, which is so chaotic, that it can effectively be used as a source of randomness.

I wanted to build a true random number generator just for fun, and to see how well it would work considering that it is fairly cheap and easy to set up.

Step 1: Materials

Arduino - ~\$30

MightyOhm geiger counter - \$100 without case, \$115 with acrylic case  (or any geiger counter with a pulse out)
http://mightyohm.com/blog/products/geiger-counter/

22 gauge solid core copper wire - \$4 (for a whole roll. You can probably even use some multi-strand wire)

salt substitute (optional) - \$4
 1-40 of 57 Next »
Fun project. The folks at mightyohm.com recommend converting the 3v pulse to 5v to hook up to the arduino, but it worked fine at 3v. Now I have more random numbers than I know what to do with.
SethT32 months ago
pavium9 months ago

The idea of using a banana as a source of radioactivity almost convinces me to have a go at this project: but Brazil nuts might be better, since bananas don't last long in my house.

Hello, I am very interested in this project.

Have you considered using the Die Hard Tests to evaluate the randomness of this solution?

I built several random number generators for the arduino platform and even though they seemed to produce random numbers, they completely failed all of the Die Hard and other tests that I did on them, meaning they weren't truly random.
I used Avalanche noise generated by a circuit (verified by an oscilloscope) and fed to an Arduino, instead of a geiger counter as you have done.

Some links: (The latter two contain programs that can be used to test randomness)

https://en.wikipedia.org/wiki/Diehard_tests

http://www.phy.duke.edu/~rgb/General/dieharder.php

https://www.fourmilab.ch/random/

nico.dejong.nz2 years ago
Hi i am wanting to build a random number generator also, I need the numbers between 1 and 90 and each number can only be used once..... do you have any suggestions for me??

thanks
1 year ago

The following code should give you a general idea

// The Entropy library provides true random numbers and can be obtained from:
#include <Entropy.h>

const byte MAX_VALUE=11;
boolean RandomDraw[MAX_VALUE];
byte tmp;

void setup() {
Serial.begin(9600);

for (int i=0; i<MAX_VALUE; i++) {
RandomDraw[i] = false;
}

// This routine sets up the watch dog timer with interrupt handler to maintain a
// pool of real entropy for use in sketches. This mechanism is relatively slow
// since it will only produce a little less than two 32-bit random values per
// second.
Entropy.Initialize();

Serial.println("Starting to draw the numbers!");
// This loop will produce the values from 1 to MAX_VALUE in random order,
// with each value only showing up once
for (int i = 1; i<MAX_VALUE; i++) {
// The do loop ensures that the selected value has not been selected before
do {
tmp = Entropy.random(1,MAX_VALUE);
} while (RandomDraw[tmp]);
RandomDraw[tmp] = true;
Serial.print(i);
Serial.print(", ");
Serial.println(tmp);
}
Serial.println("Finished!");
}

void loop() {
}

1 year ago

You can't have "random numbers" which also meets the constraints of 1-90 but only once. The whole point of random numbers is that you can't predict what subsequent values will be. So in your case, after generating 89 numbers, I would be able to predict with 100% accuracy what the 90th number would be!

mickeypop3 years ago
Nice Idea, but the \$100 for the geiger counter part can be done cheaper.

Look on the web for hacking a smoke detector.

They work much the same. They have a small isotope and sensor when smoke particals pass between the two they trigger reaction much like the geiger counter.

A cheaper source of random triggering components. Just make the chamber a bit larger to your liking and tweak the trigger thresholds and your in business. Oh yea, disable the alarm too, its a bit load.

Another approach, put the the isotope aside ( in a metal box, it is radioactive ) and point the sensor to the sun.  The sensor will usually react to the small gama from the sun's rays.

Though I was not looking to make a random numbers generator, about 7 years ago I needed to develop a particulate detector and found that interfacing to the smoke detector turned out to be quite easy and just needed to change the thresholds to my needs.

Hope this can help anyone trying to save a bit to develop on your idea.
1 year ago
Mickey,
I think this is actually not the case. The sensor in the Am-241 smoke detectors does not detect individual gammas. It compares the electrical currents through two ionization chambers: one that's open to air versus a sealed one for reference, both irradiated to ionize air in them. Smoke reduces ion mobility in the open one, hence measurable difference in current. Your particle detector from 7 years ago perhaps reacted to ionization current by UV light that affected one chamber more than the other...?
cheers, M
1 year ago
Actually you are both right and wrong.

There are 2 types of smoke detectors out there on the market.
1.  Ionization based, these are very fast but also cost more
2. particle based, these though the do use an isotope, they look at a capacitive difference between chambers enough to trigger a response when particles pass into one of the chambers.

you need the second type because they use a radioactive isotope that randomly decays.

You don't tap the output from the control chip, that would be as you said true.

You want to tap one of the inputs to the control chip so you are getting the decay not the comparison.

By picking up the gamma pulses on the trigger plate you are getting the randomness of the decay itself and not the decision making of the control chip, thus, it's random.

Hope that clears any the difference.

1 year ago
Hi Mickey, thanks for coming back, but this would not be the case.

1. Ionization type is the one with the Am-241 source. Nowhere in the device would there be pulses from detection of individual gammas or individual alphas. The mechanism is that alphas, ionize air and make it conductive. Even with an ideal scope, you would not see pulses because the ions take quite a while to travel to capacitor plates, hence all signal is smeared out to DC current.

2. The other type is called optoelectrical and simply observes light scattering.

I can see that you don't believe me on this topic. Would you take it from another source? http://en.wikipedia.org/wiki/Smoke_detector
Knoll's or Leo's textbooks on radiation detection are also nice.

with kind regards, Matjaz
3 years ago
I've heard of a similar hack but with the isotope placed into a dark box with a cmos camera aimed at it. Each particle that hits the cmos at any given time will show up as a pixel of light. The program interprets each pixel in the camera's resolution as a certain number in a range. Whichever pixel "lights up" is the number chosen at random by the isotope.
coolsciencetech (author)  mickeypop3 years ago
Thanks for the suggestions, I'll definitely look up the smoke detector hack!
endolith3 years ago
You don't need a Geiger counter for this. The noise in your Arduino's ADC is random enough.
3 years ago
Probably not random enough. Some people have apparently tested the TrueRandom library for Arduino, which uses the Analog 0 pin, open, as a noise source.

Problem is, it doesn't pass ANY of the NIST randomness tests, and it should pass all of them. I highly doubt it would pass any of the DieHard tests of randomness, either.

I don't know if that's due to software insufficiency, lack of entropy in the noise in the analog pin (due to digital quantization), or both. A simple avalanche diode setup or noise generator amplified and piped into the analog pin would help with this tremendously.
3 years ago
"TrueRandom does it by setting up a noisy voltage on Analog pin 0, measuring it, and then discarding all but the least significant bit of the measured value."

That sounds dumb. Aren't they just throwing away entropy? When I did a similar program on a micro, the LSB and MSB never changed! I would think the best thing to do is read the ADC, bitshift, read the ADC, XOR with previous measurement, bitshift, read the ADC, etc. for all 8 bits, so that any true randomness on one bit becomes randomness of all bits.

From Wikipedia:

"Problems

It is very easy to misconstruct hardware or software devices which attempt to generate random numbers. Also, most 'break' silently, often producing decreasingly random numbers as they degrade. A physical example might be the rapidly decreasing radioactivity of the smoke detectors mentioned earlier. Failure modes in such devices are plentiful and are complicated, slow, and hard to detect."

:/
3 years ago
Yeah, that's why it's good to constantly sample the randomness stream and test it for quality, as well as do a thorough test every now and then.
3 years ago
I've been gathering data from TrueRandom trying to get enough to run dieharder on it, but then discovered "ent", which works with any size data, and TrueRandom doesn't seem to test very well with even the most basic tests:

https://gist.github.com/2472824

Assuming I did it correctly, it's skewed toward producing lots of 0s and other low numbers.

I'd like to see this test done on the geiger counter version.

I have an idea for a way to get better results out of the Arduino's ADC, though. Need to write it and test it.
3 years ago
Nifty!!

Have you tried building a noise circuit? This is similar to one of the designs I've wanted to build, but have never gotten around to it:

https://mywebspace.wisc.edu/lnmaurer/web/minirng/minirng.html
2 years ago
I wrote an Arduino program to generate true random numbers using the drift between the oscillators: https://gist.github.com/endolith/2568571#file-readme-md

It only produces 64 bits per second, though.
2 years ago
Awesome! I was looking into osc jitter, because it has the potential to be very, very fast (commercial chips using thermal noise modulating oscillator jitter get many kilobits/s), but that's very dependent on hardware.

Since my last comment, I've gotten a couple reverse-biased N3904 transistor avalanche based noise generators going that generate adequate randomness at 500 bits/s, but have some bias issues I'm still trying to hammer out.

The really brutally fast RNG chips (a few Mbit/s) use lasers with half-silvered mirrors, going off of the quantum randomness of whether a photon is scattered or passed through. Doable at the hobby level, but takes more dedication than I'm willing to commit right now :P
2 years ago
That's crazy. What do you need Mbit/s of random numbers for, (besides running random.org)?
2 years ago
Not much :P. The only things I can think of that would use that much entropy are high-end Monte-Carlo modelling simulations (like weather modelling, neutron transport), extreme cryptographic applications, and micro-psychokinesis experiments, and that's about it, with simulations probably representing the bulk of that.
2 years ago
Ahh, simulations. That makes sense.
3 years ago
No, but that should work well.

I was trying to get noise just from the internals of the IC without depending on anything else, but was not very successful.

Idea was read the ADC, XOR with previous reading, bitshift by 1, read the ADC, XOR with previous reading, etc. for every bit of output, so that the randomness of the least significant bits gets spread around to all the bits. The problem is that the ADC readings barely ever change. There's barely any noise there. On another micro I used, the first 10 bits would be the ADC value, and then there would be a few extra bits of noise after that. On the ATMegas, they just return 0 for the last few bits, so there's nothing to use:

228
227
228
227
228
228
228
228
228
228
228
228
228
228
228
228
228
228
228
228
226
228
228

If you read the ADC 50 times per output byte, it gets somewhat better, but still not good enough:

Entropy = 7.318613 bits per byte.

Optimum compression would reduce the size
of this 65149 byte file by 8 percent.

Chi square distribution for 65149 samples is 357188.56, and randomly

would exceed this value 0.01 percent of the times.

Arithmetic mean value of data bytes is 116.0950 (127.5 = random).
Monte Carlo value for Pi is 3.287529932 (error 4.65 percent).
Serial correlation coefficient is 0.062505 (totally uncorrelated = 0.0).

I'm not sure what other entropy sources would be inside the IC. I tried measuring the time for an ADC conversion, and it changes more than the ADC result itself, but still seems very deterministic.
2 years ago
Unfortunately, Instructables does not allow us to edit posts, so I cannot edit this to say that it is wrong, but it is wrong. The ADC on the Arduino microcontroller has very little randomness, because those bits are trimmed off and stay at 0 all the time.
2 years ago
2 years ago
Yeah, but then the context of the thread is destroyed
2 years ago

They concluded that nothing you do can make it random enough to pass simple randomness tests consistently, and even provide a program to quickly guess the seed that was used given a sequence of bits from the PRNG.
2 years ago
Yeah, there's essentially no randomness in the Arduino's ADC. I was thinking of another micro, which has plenty, but on the Atmel chips the noisy bits are silenced for some reason.

I wrote some code to generate truly random numbers which seems to work pretty well: https://gist.github.com/endolith/2568571 Only 64 bit/s though.
rimar20003 years ago
Very clever! Normally random numbers generators use time, and because that they aren't really random numbers generators.
3 years ago
That's a bit off. If a random number generator uses time then it probably is a TRULY random number generator. Fake random numbers, or Pseudo Random Number Generators (PRNG), usually use a type of mathematical function that can be used like a blender for numbers. The problem is that PRNG functions will blend numbers exactly the same way every time you use them, so even though the blended numbers may be well distributed they are predictable, thus not truly random. The make them unpredictable a truly random "seed" is added to the mix while blending. Finding true random numbers isn't very hard. The problem is finding enough of them to be useful. Computers need lots of random numbers for various things (mostly games and cryptography). If your computer could make as many true random numbers as it needed then it wouldn't need a PRNG.(*) One of the most common ways to generate a true random number is to use an unpredictable event to trigger the sampling of a clock. Measuring the time it takes a human to move a mouse or type on a keyboard is a common source of true random numbers. Many operating systems constantly measure these sorts of events and store the random numbers in a big pool to used when needed. This is called an "entropy pool" in the Linux operating system.

(*) Actually, most a sources of true random numbers are not well distributed, so even if you had plenty of them the numbers would still be put through a mathematical blender to smooth them out so that they are well distributed as well as truly random.
3 years ago
Thanks for the info, noahspurrier. I am always struck by the lack of randomness in sets of numbers obtained with some methods, which I assumed based on time.
4lifenerdfighter3 years ago
Sorry. This isn't TRULY random. Nothing can be. This bases its generation on an outside event, which means it could be manipulated if someone could figure it out. Not random. But, your method IS very good at generating numbers.
3 years ago
Quantum events like alpha and beta decay are truly random events.  The best you can do to predict them is to give their average rate of decay, which is the half-life.

To wrap your head around this, recognize that ALL atoms in a cluster of isotope atoms are unstable, and ALL of them must decay.  However, a given atom in 5 pounds of radon might decay a second from now, or it might not decay for ten thousand years.  There is no way to predict when one will decay, even in theory.  The best you can do is say that in about 4 days there will only be 2.5 pounds of radon left, and the rest will be Polonium.

You can certainly build RNG seeded from a truly random source that isn't truly random - the easiest way is to use equipment that isn't sensitive enough.  If you are getting bursts of alpha particles every 10 microseconds, a detector with millisecond resolution isn't going to be fine enough to detect the small random differences in decay time.

However, a properly written RNG algorithm seeded with a number from a sufficiently sensitive detector of a truly random source will be truly random.
3 years ago
Yes, it is true random. If I have a geiger counter driven RNG in a locked, shielded box in my room with software I wrote, it's a quantum mechanical process - it's truly random, and it's not getting compromised unless someone gets physical access. And if they have physical access, I have bigger problems at hand.
wandrson3 years ago
Nice write-up. You should credit your algorithm (using the time difference between four events with the source; http://http://www.fourmilab.ch/hotbits/

Also, using millis, is not likely to be a fine enough measure. When I constructed my version, I noticed that the bit stream had a significant bias using millis on an arduino for time measurement. I ended up having to use microseconds instead.

Further, when I have produced several million bytes of entropy I noticed that the algorithm was still producing a bias for bytes>127, which I was able to remove by XORing two consecutive bytes together.

To speed up the generation of entropy, you can obtain small (safe) mineral samples of uranium (~\$20) from unitednuclear.com. They also sell isotope sources that work even better (and are still safe). These can increase the count level to several thousand counts per minute. A much faster bit stream
coolsciencetech (author)  wandrson3 years ago
Thanks for reminding me about fourmilab, I'll put up a link to their site. I had done a bunch of reading on it before starting this project and didn't really remember where I found the algorithm. I'll also update the code to use microseconds instead of millis!
kelseymh3 years ago
This is an awesomely cool project :-) I especially like your use of NoSalt as a 40K gamma source. You could also use bananas if you're so inclined ;-)
3 years ago
I think for the purposes of encryption and the building of an encryption key, I'd definitely use bananas. that way I could tell people that my data is "banana encrypted."

either that or say it's guarded with bananas. or something else ridiculous.
 1-40 of 57 Next »