As a followup of the discussion in this thread, I decided to look at the frequency distribution of values you get by using analogRead() on a floating (unconnected) analog pin.
Background
A "good" random number generator should have a "flat" frequency distribution (equal probability of getting any number in range) - which of course is unlikely in this approach. The better approach is to "seed" the default pseudorandom generator in Arduino library - which does approximate to flat distribution - with some kind of random value - either a timer counter or as discussed in the post, analogRead() on a floating pin. The seed should be a fairly random, wide ranging number.
Test
I generated 1 million values from analogRead() on a floating pin, sent each value to my computer using serial & built a frequency distribution in excel.
Results
99.5% of the 1 million values were distributed between just 38 values out of 1024 possible values. Hmmm.... does not seem to be a wide "seed" range by any means
I decided to look at the frequency distribution of values you get by using analogRead() on a floating (unconnected) analog pin.
With an Uno? Did you also test the Mega? What about the bigger Mega? The Teensys? What about when the Teensy is plugged into a breadboard? What if a neighbor pin is generating a PWM signal? What if a neighbor pin is HIGH? Or LOW? What if the board is powered by USB? What if the board is powered from VIN? What happens when the board is placed close to a desk lamp? Did you try the board near an OttLite? What happens when your hand is close to the pin? What about your mobile phone? Did you test after running the air conditioner a bit so the air is drier?
The point is, an unconnected pin is a terrible way to generate a random number. Even if you get good results some of the time there is no way to guarantee good results all of the time. AWOL's suggestion helps in the case that the voltage is changing but it obviously won't help in the copious cases that the voltage is not changing or is heavily influenced by something near.
You are entirely correct. I did extensive research on this and essentially debunked this claim made by Arduino. I did not find a stable and viable way to generate randomness on-board the Arduino.
srinathdevelopment: Results
99.5% of the 1 million values were distributed between just 38 values out of 1024 possible values. Hmmm.... does not seem to be a wide "seed" range by any means
Comments / Thoughts welcome.
That's what cryptographers use hash functions for - take a sample of the bottom bits of the values and put them through a hash function (CRC32, MD5...whatever size you need).
The stock analogRead() is essentially incorrectly coded.
I did a Chi-squared test on about 7k data points and it passed with flying color using the revised myanalogRead() provided in that thread. The distribution is also quite uniform.
It also talked about other ways to potentially produce truly random numbers from your arduino. The rc oscillator approach for example can be done with just a resistor + cap + onboard comparator.
The ideal is solid, except it is incorrectly implemented.
dhenry:
I did a Chi-squared test on about 7k data points and it passed with flying color using the revised myanalogRead() provided in that thread. The distribution is also quite uniform.
The floating analog pin is an antenna receiving signals. The ADC converts this to 10 bits. Depending on what the analog pin receives the result will be more or less random.
What does the antenna receive? signals from all electronics in the neighbourhood and beyond ...
True randomness is very difficult to reach imho (although the frequency of this topic popping up in this forum is quite random
Depending on what the analog pin receives the result will be more or less random.
That is true but it ignores the issue that the distribution of that randomness is not desirable - which is the point raised by the paper cited in this thread, putting aside 1) the loading by the adc module; and 2) the inherent issue with the analogRead() call, well documented in a separate thread.
Thus, the lsb approach. It actually doesn't rely on the randomness of a signal on the adc pin, but the randomness of the last digit returned by the adc process. You can tie the pin to a known voltage (Vcc or ground), yet the adc's lsb is unstable.
Obviously, adc'ng a floating pin adds more uncertainty to the process.
dhenry:
Thus, the lsb approach. It actually doesn't rely on the randomness of a signal on the adc pin, but the randomness of the last digit returned by the adc process. You can tie the pin to a known voltage (Vcc or ground), yet the adc's lsb is unstable.
Nope. The technique failed again. Analog input 1 ... failed. Analog input 2 ... failed. Speed up the ADC clock ... failed. Speed it up even more ... failed. Set it to the value used in the core ... failed.
It actually doesn't rely on the randomness of a signal on the adc pin...
It may not but it most certainly does not work the way you described.