Random number generator (Part 3)

Part 1, 2, 3

The early tests presented in this series of posts were dealing with a limited number of data. The risk exist that a long term repeated pattern may not be seen using these statistical tools. Here is an other approach to testing the randomness of data.

It consists in creating a black and white bitmap made out of millions of data points, each of them representing a unique random value. Although the result is a flat image, using gray scale for each cell from the matrix allows a clean and easy 3D graphical representation of these data points. The size of the matrix depends on the range of the random values. If the random values ranges from 1 to 65536 (so as to say 2^16), the matrix shall be squared and each side will be 256 (so as to say 2^8) cells wide. Each time the random number matches a cell, the content of this cell is increased resulting in brighter pixels. The test stops when a cell achieves the maximum brightness.

Here is a sample from multiple tests that I ran using the previously described hardware random generator:

pixels_map_9

As you can see, this image looks like sand paper without any obvious pattern. Compare it to the next one that I obtained after tweaking the biasing mechanism:

pixels_map_7

Interesting, isn’t it ?

Ultimately, these are the few lines of code that I used in processing for reading data out of Arduino and plotting random values. Oh! By the way, the random() function gives a very… random bit map too !

import processing.serial.*;

Serial myPort;

int _plotWidth;
int _plotHeight;
long _counter = 0;
float _maxBright = 0;
volatile int _inByte;
volatile boolean _readStatus = false;


void setup() 
{
  /* Set graphics */
  size(256, 256);
  _plotWidth = width;
  _plotHeight = height;
  colorMode(RGB, 255);
  background(0); 
  frameRate(60);
  /* Set serial port */
  String portName = "COM29";
  myPort = new Serial(this, portName, 1000000);
}



void draw()
{  
  _counter= 0;
  _maxBright = 0;
  clear();
  background(0); 
  loadPixels();
  while(true) {
    int data = 0;
    for (int i = 0; i < 2; i++) {
      _readStatus = false;
      while (_readStatus == false);
      data <<= 8;
      data |= _inByte;
    }

    // data /= 64;
    /* Get the actual pixel color */
    float actColor = red(pixels[data]);
    float newColor = (actColor + 4.0);
    /* Record maximum brightness */
    if (newColor > _maxBright) {
      _maxBright = newColor;
    }
    /* constrain brightness */
    if (newColor > 255.0) {
      break;
    }
    int c = color(newColor);
    pixels[data] = c;
    _counter += 1;
   
    print(_counter); 
    print(";");
    print(data); 
    //print(";");
    //print((newColor)); 
    print(";");
    print((_maxBright)); 
    println();
  }
  updatePixels();
  save("pixels_map.tif");
  //delay(2000);
  while(true);
}


void serialEvent(Serial myPort) 
{
  _inByte = myPort.read();
   //myPort.clear();
  _readStatus = true;
}

This is real raw code, however it does the job nicely and snappy. Note that the bitmap image is recorded in a compressed lossless TIF format so that it could be analyzed after acquisition.

Next is a copy of the code taken from one of the examples prepared for PlainRNG library. Setting the random number generator is plain easy. This code generates unsigned 2 bytes random numbers for ever and matches the processing code as shown above.

/*

	PlainRNG library, hardware random numbers generator library
	Copyright (C) 2016 Didier Longueville

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
*/

#include <PlainRNG.h>
PlainRNG RNG;

const uint8_t _adcPin = 0;

void setup()
{
	/* Initialize serial port */
	Serial.begin(1000000);
	/* Initialize analog port */
	RNG.InitializeRNG(_adcPin); 
	RNG.Calibrate(32768); 
}


void loop()
{
	uint8_t rn = (RNG.RandomNumber(8, BIA_REM_VON_NEUMANN) & 0xFF);
	Serial.write(rn);
}

 

Enjoy and keep me posted with your comments.

Leave a Reply

You must be logged in to post a comment.