# Best way of random seed

I read a bunch of stuff, but I'm not able to get the best practice to generate "real" random number, i.e. numbers with a large entropy every single time. I understood that the key is to choose a good random seed.
I need a random for a uint32. I tried as randomSeed() both millis() and analogRead() of a disconnected pin.
With the first one, I get always increasing random numbers. With the second I get "very close" numbers. Big failure.

So, what's the point of having a random() function when I actually have to generate myself the random seed with large entropy? At the end I end up writing the random() myself Is there any best practice?

The point of having a random() function is speed, especially when you need more than 1 random number in your program. A good seed could take 100ms. While calling random() takes a fraction of that time.

As a seed you could take the LSB of analogRead() on a disconnected pin and read it multiple times to construct your seed.

A good question to ask yourself is how random do they really need to be? What is the purpous of your random number?

If you really need a good random seed (or random numbers), you can use the Entropy library:

(assuming you are using a board that is supported by the library)

I need it to assign UUID so that the collision of two identical UUID is statistically improbable.
For the small number of UUID I need, a uniformly distributed random in 0-uint32MAX is good enough, and the Entropy library seems to have what I need :).
Thanks.

Its very hard to generate entropy in a small deterministic microcontroller. If you just need a static UUID you
can use a unique ID chip like the 11AA02E48 http://ww1.microchip.com/downloads/en/DeviceDoc/11AA02E48-11AA02E64-2K-UNIO-Serial-EEPROMs-Data-Sheet-20002122E.pdf

A good question to ask yourself is how random do they really need to be? What is the purpous of your random number?

Random enough" is where I always start - You can get deeply into the philosophy of randomness or you can simply shoot for something “humanly unpredectable”, etc.

One way to improve it is to use millis() with a push-button so it “grabs” a seed when you press the button (if that’s practical for your application).

Or, I haven’t tried this but you could attach a “long wire” to a floating analog pin to act as an antenna picking-up the electromagnetic AC power line radiation. (If you’ve ever touched an audio input and heard a “buzz”, that’s what I’m talking about.) Of if your device has a power supply with a regular AC transformer you can tap-into the transformer secondary (after biasing and adjusting the voltage as necessary). Or you could build sine-wave or triangle wave oscillator to generate “random” analog readings.

Jane Nordholt’s Entropy Engine, currently a hot selling item for those who want to generate random seed numbers, uses the chaotic jostling of photons to generate random numbers.

Try this:

``````// random seed 1.04
//
// produces a generally random number based on processing
// error voltages from the readings taken from the analog to digital
// conversion port
// on the Arduino

// 2016-02-17 32 bit test/demo version

const byte analogPort = A1;

const int BUCKET_SIZE = 64;
int buckets[BUCKET_SIZE];

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

void loop() {
long temp = getRandomSeed(31);
buckets[temp%BUCKET_SIZE]++;

for (int i = 0; i < BUCKET_SIZE; i++)
{
if (buckets[i] == 0)
{
Serial.print(' ');
}
else
{
Serial.print(buckets[i]);
}
Serial.print(' ');
}
Serial.println('*');
}

long getRandomSeed(int numBits)
{
// magic numbers tested 2016-03-28
// try to speed it up
// Works Well. Keep!
//
if (numBits > 31 or numBits <1) numBits = 31; // limit input range

const int baseIntervalMs = 1UL; // minumum wait time
const byte sampleSignificant = 7;  // modulus of the input sample
const byte sampleMultiplier = 10;   // ms per sample digit difference

const byte hashIterations = 3;
int intervalMs = 0;

long result = 0;
int tempBit = 0;

Serial.print("randomizing...");
pinMode(analogPort, INPUT_PULLUP);
pinMode(analogPort, INPUT);
delay(200);
// Now there will be a slow decay of the voltage,
// about 8 seconds
// so pick a point on the curve
// offset by the processed previous sample:
//

for (int bits = 0; bits < numBits; bits++)
{
Serial.print('*');

for (int i = 0; i < hashIterations; i++)
{
//      Serial.print(' ');
//      Serial.print( hashIterations - i );
delay(baseIntervalMs + intervalMs);

// take a sample
tempBit ^= reading & 1;

// take the low "digits" of the reading
// and multiply it to scale it to
// map a new point on the decay curve:
intervalMs = (reading % sampleSignificant) * sampleMultiplier;
}
result |= (long)(tempBit & 1) << bits;
}
Serial.println(result);
//  Serial.println();
return result;
}
``````
1 Like