Generating random numbers electronically

Thread Starter

k1ng 1337

Joined Sep 11, 2020
85
Hi I am interested in the different electronic methods used to generate (pseudo) random numbers for use with an Arduino. So far I have used the seed function with a floating analog input to generate this sequence of numbers and after some close inspection it looks pretty random! My function generates a new seed on every loop but I am unsure "how random" the value really is. I have monitored the floating input in 10 bit resolution on the Arduino and the value does indeed vary substantially. This leads me to believe the value that has been obtained is from a near random process but is still within many parameters that make it not random; which is to say: The value started random but is now defined via the processor.

What are common random processes used to generate these seeds? As well as random bits at the analog level?
 
Last edited:

Papabravo

Joined Feb 24, 2006
16,159
Hi I am interested the different electronic methods used to generate (pseudo) random numbers for use with an Arduino. So far I have used the seed function with a floating analog input to generate this sequence of numbers and after some close inspection it looks pretty random! My function generates a new seed on every loop but I am unsure "how random" the value really is. I have monitored the floating input in 10 bit resolution on the Arduino and the value does indeed vary substantially. This leads me to believe the value that has been obtained is from a near random process.

What are common random processes used to generate these seeds?
What you see is mostly an illusion of randomness. Humans are actually very bad at spotting randomness. Among the processes that are thought to be more random than any pseudo-random computer algorithm is beta-decay of a radioactive isotope. Knuth devoted a whole chapter to these algorithms and processes in Volume 3, Chapter 3 of TAOCP

Beta decay - Wikipedia
The Art of Computer Programming - Wikipedia
 

nsaspook

Joined Aug 27, 2009
8,384
Last edited:

MrChips

Joined Oct 2, 2009
23,535
Here is a test you can perform.
Take two random numbers in succession.
Scale the numbers to fit the size of your graphics screen.
The two numbers will give you a pair of Cartesian coordinates (x,y).
Plot a point (i.e. turn on the pixel at this location).
Do this repeatedly without reseeding the random number generator.
 

dendad

Joined Feb 20, 2016
3,835
One way you can go is using an external noise source. For example...
http://holdenc.altervista.org/avalanche/
Feed the noise to a pin and use multiple reads to set each bit, or have multiple noise sources to read more than one but at a time.
There was a classic random number generator based on lava lamps too!
 

atferrari

Joined Jan 6, 2004
4,327
Here is a test you can perform.
Take two random numbers in succession.
Scale the numbers to fit the size of your graphics screen.
The two numbers will give you a pair of Cartesian coordinates (x,y).
Plot a point (i.e. turn on the pixel at this location).
Do this repeatedly without reseeding the random number generator.
Sorry MrChip
My two numbers are 938 and 67. Could you explain the above based on them?
Gracias.
 
Last edited:

andrewmm

Joined Feb 25, 2011
1,473
Re test for randomness,
https://en.wikipedia.org/wiki/Randomness_test

There are many tests, but all have pit falls,

e.g. assuming your after white noise, then simple first test

a) probability of each number is equal over sufficient time
b) All number in the range are present

But this test fails the predictability test ,
i.e. a counter of 0 to 255 passes that test.


How to generate,
falls into two areas, sequence , and noise source.

A sequence , is just that , Sonner or later it will repeat.
There can be ways of making the sequence less predictable, by adding a "random" input every now and then, such as time between key presses , but that's not to random.


Noise generators use just that, examples the "random" noise of a fet junction, or the random interaction between a number of free running oscillators,

All have problems, the bandwidth of fet noise is low, so new numbers can only be acquired infrequently ,
multiple oscillators are surprisingly hard to keep independent and not let them synchronise.

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

peterdeco

Joined Oct 8, 2019
357
There are several ways a microcontroller can generate random numbers. They way I did it was as soon as a button is pressed, the uC began counting from 0 to 7 for 8 random numbers. When the button is released, the last number it counted made the corresponding output high. Since the counting is done in microseconds, the last number generates a random output.
 

ElectricSpidey

Joined Dec 2, 2017
1,656
In my recent projects I've been using a LM34 and a ADC to generate the seed, but I'm not creating anything special with the generated numbers, so it's good enough for my usage.
 

andrewmm

Joined Feb 25, 2011
1,473
There are several ways a microcontroller can generate random numbers. They way I did it was as soon as a button is pressed, the uC began counting from 0 to 7 for 8 random numbers. When the button is released, the last number it counted made the corresponding output high. Since the counting is done in microseconds, the last number generates a random output.
@peterdeco, not heard that one before, would be interesting to see how random it is, Did you make any histograms ?
 

MikeA

Joined Jan 20, 2013
254
You can rig up an ESP8266 and WGET someone's twitter feed, say like AOC, then convert the letters to number strings. You'll definitely be getting an endless stream of wacky random numbers. ;)
 

Papabravo

Joined Feb 24, 2006
16,159
You can rig up an ESP8266 and WGET someone's twitter feed, say like AOC, then convert the letters to number strings. You'll definitely be getting an endless stream of wacky random numbers. ;)
They will be biased by the nature of natural language and thus not truly random. They will only seem random. This is actually a fruitless task you are engaged in. There is no way for an algorithm to achieve randomness and avoid determinism.
 

Thread Starter

k1ng 1337

Joined Sep 11, 2020
85
They will be biased by the nature of natural language and thus not truly random. They will only seem random. This is actually a fruitless task you are engaged in. There is no way for an algorithm to achieve randomness and avoid determinism.
As interesting as they are, the methods presented in this topic do appear to be deterministic. It seems to me that whatever method used to generate a seed will always be restricted by whatever processor is computing it because the processor has already been defined via its machine code. I can think of endless ways to generate a seed, but that seed will always be processed in some predictable way and every additional attempt to reduce this effect will invariably lower the entropy of the system.
 

xox

Joined Sep 8, 2017
565
As interesting as they are, the methods presented in this topic do appear to be deterministic. It seems to me that whatever method used to generate a seed will always be restricted by whatever processor is computing it because the processor has already been defined via its machine code. I can think of endless ways to generate a seed, but that seed will always be processed in some predictable way and every additional attempt to reduce this effect will invariably lower the entropy of the system.
I came up with an interesting method some years back that generates "truly" random numbers by taking advantage of subtle differences in execution time between clock ticks. I say "truly" because it depends on a few assumptions, namely that the program is NOT running in a virtual machine and second that the timing differences are inherently stochastic. The latter is practically guaranteed with modern day multitasking operating systems. Whether or not it can be adapted to a particular embedded system however remains to be seen.

Code:
#include <limits.h>

typedef unsigned long long word;

#ifdef _WIN32
#include <windows.h>
word tick() {
  unsigned __int64 tock;
  QueryPerformanceCounter((LARGE_INTEGER*)&tock);
  return (word)tock;
}
#else
#include <time.h>
word tick() {
  return (word)clock();
}
#endif

word random_bits(int bits) {
  /*
      The `threshold` setting determines the smallest sample to extract a bit
      from. If set too low the result won't contain enough entropy to be useful.
      We don't want to set it so high that we're just wasting CPU cycles either
      however so we need to settle on a value somewhere in the middle.
      Heuristically at least 256 seems to be a pretty good compromise.
  */
  const word threshold = 256;
  word result = 0, increment, accumulator, count, target;
  const int size = sizeof(result) * CHAR_BIT;
  if (bits == 0 || bits > size)
    bits = size;
  while (bits-- > 0) {
    increment = 1;
    accumulator = 0;
    /*
        Build up the accumulator. We don't know anything about clock
        resolution, so the increment is simply doubled until it becomes
        large enough to make a difference.
    */
    while (accumulator < threshold) {
      count = 0;
      target = tick() + increment;
      while (tick() < target)
        ++count;
      accumulator += count;
      increment <<= 1;
    }
    /*
        Insert the sample bit.
    */
    result <<= 1;
    result |= (accumulator & 1);
  }
  return result;
}

#define random_word() \
random_bits(sizeof(word) * CHAR_BIT)

//    Sample usage:

#include <stdio.h>

int main(void) {
  for (;;) {
    printf(" %llu\n", random_word());
    //getchar();
  }
}
It's obviously not the most efficient way to generate random numbers, but if you simply don't have access to something like /dev/urandom or what have you it might be a decent option.
 
Top