If your application has an ethernetshield one could call - RANDOM.ORG - Byte Generator
And so I build this prototype . It is a simple webclient that asks for 4 bytes and converts this output to a long. If the network connection fails the internal random() function is called as a backup.
/*
* FILE: randomNet
* AUTHOR: Rob van den Tillaart
* DATE: 2011-01-06
* VERSION: 0.2
* PURPOSE: fetch a random long over the net from www.random.org
*/
#include <SPI.h>
#include <Ethernet.h>
byte mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[4] = { 192, 168, 1, 25 };
byte server[4] = { 174, 143, 173, 125 }; // nslookup www.random.org
long fetchRandomLong()
{
long rv = -1;
byte ch;
int state = 0;
int x = 0;
Client client(server, 80);
if (client.connect())
{
// client.println("GET /decimal-fractions/?num=1&dec=8&col=1&format=plain&rnd=new");
client.println("GET /integers/?num=4&min=0&max=255&col=1&base=10&format=plain&rnd=new");
// wait max 1 second to read the answer
for (int i=0; i< 1000; i++)
{
if (client.available()) break;
delay(1);
}
// fetch the string
while (client.available())
{
ch = client.read();
if ('0' <= ch && ch <= '9')
{
state = 1;
x = x*10 + ch - '0';
}
else
{
if (state == 1)
{
state = 0;
rv <<= 8;
rv += x;
x = 0;
}
}
}
client.stop();
for (int i=0; i<100; i++)
{
if (client.status() == 0) break;
delay(1);
}
}
// network did not work => use internal as backup
if (rv == -1)
{
rv = random();
}
return rv;
}
////////////////////////////////////////////////////////
void setup()
{
Serial.begin(115200);
Serial.println("Demo - random from www.random.org");
Ethernet.begin(mac, ip);
delay(1000);
}
void loop()
{
unsigned long start = millis();
long rd = fetchRandomLong();
unsigned long timeUsed = millis() - start;
Serial.print("random : ");
Serial.println(rd);
Serial.print("time : ");
Serial.println(timeUsed);
}
// END OF FILE
Sample of the output
Demo Random via net
random : 1346747051
time : 1033
random : -1992743329
time : 705
random : -629485075
time : 795
random : 491946319
time : 532
random : -1748141667
time : 623
random : -1086788461
time : 1096
random : 907126690
time : 1187
random : -1270226305
time : 911
random : 605004460
time : 851
random : -1837384756
time : 692
The randomness of the numbers is guaranteed by the organization behind the webserver www.random.org. The timing is almost a random generator in itself as it differs quite alot. Average timing varies around 750-800 millis(). The code size is 6840 (IDE 21 - UNO).
The code is bigger and slower than the random function based upon the internal temperature sensor ans so we can conclude that true randomness has its price.
TODO:
- a minimal improvement would be ask for two 16 bit numbers
- fetchRandomFloat()