Random Function based upon internal temp sensor

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()