_                           _    _____                      _ _           ____  _             
      | |                         ( )  / ____|                    (_) |         |  _ \| |            
      | | __ _ _ __ ___   ___  ___|/  | (___   ___  ___ _   _ _ __ _| |_ _   _  | |_) | | ___   __ _ 
  _   | |/ _` | '_ ` _ \ / _ \/ __|    \___ \ / _ \/ __| | | | '__| | __| | | | |  _ <| |/ _ \ / _` |
 | |__| | (_| | | | | | |  __/\__ \    ____) |  __/ (__| |_| | |  | | |_| |_| | | |_) | | (_) | (_| |
  \____/ \__,_|_| |_| |_|\___||___/   |_____/ \___|\___|\__,_|_|  |_|\__|\__, | |____/|_|\___/ \__, |
                                                                          __/ |                 __/ |
                                                                         |___/                 |___/ 
    Home    Twitter: @Xtrato    Email: james[at]jamesdotcom.com    PGP Key    GitHub: Xtrato    Youtube: Xtratozorz    RSS Feed

11th May 2013 || True Random Number Generator using the Raspberry Pi

Last weekend i made my Raspberry Pi into a true random number generator using the static from a TV. Here in the UK we no longer receive analog terrestrial broadcasting so finding static on my TV is as simple as putting it on the analogue channel.

The setup i was using is an eSecure USB 8MP webcam plugged into the Raspberry Pi and i pointed this at the TV. I used a python script to calculate the random numbers. I also made a video of the process which can be found at this link here.

The first step was to take a picture of the static on the TV. To do this i used the subprocess module in python.

captureImage = subprocess.Popen(["fswebcam", "-r", "356x292", "-d", "/dev/video0", "static.jpg", "--skip", "10"], stdout=devNull, stderr=devNull)
captureImage.communicate()

As you can see this simply spawns the fswebcam process to take a picture and save it as static.jpg. Examples of these photos can be found Here and Here:

The next stage is to convert these images into a black/white image. I imported the Python image library into my script to manipulate and read the image files.

staticImage = Image.open("static.jpg")
bW_Image = staticImage.convert('1')

Two examples of these black and white conversions can be found Here and Here.

The next stage was to iterate over the static image and read the value of each pixel. Each value being either 0 or 255 depending on if the pixel was white or black. The value was entered into a variable called randomBits with 0 for a white pixel and 1 for a black pixel.

	
while pixelRow < staticImage.size[0]:
    while pixelColumn < staticImage.size[1]:
        if imageToProcess[pixelRow, pixelColumn] == 0:
            randomBits = randomBits + "0"
        else:
            randomBits = randomBits + "1"
        pixelColumn = pixelColumn + 1
    pixelRow = pixelRow + 1
    pixelColumn = 0

This randomBits variable is then written to an output files as a base 10 number. This means that the long binary string is converted to a decimal value and written to the output file. This decimal number is the random value calculated from the image.

output = open('output.txt', 'w')
    output.write(str(int(randomBits, 2)))
    print int(randomBits, 2)
    output.close()

The full source code can be copied from below:

import Image
import subprocess
devNull = open('/dev/null', 'w')#used to output the fswebcam stdout and stderr
name = 0
while True:
    name = name + 1
    randomBits = ""
    pixelRow = 0
    pixelColumn = 0
    captureImage = subprocess.Popen(["fswebcam", "-r", "356x292", "-d", "/dev/video0", "static.jpg", "--skip", "10"], stdout=devNull, stderr=devNull)
    captureImage.communicate()#executes the command detailed above with takes a picture using the webcam
    staticImage = Image.open("static.jpg")#Opens the image
    bW_Image = staticImage.convert('1')#Converts the image to a black or white image
    imageToProcess = bW_Image.load()#Saves the image to a variable that can be iterated through
    while pixelRow < staticImage.size[0]:#Iterates through the image pixel by pixel
        while pixelColumn < staticImage.size[1]:
            if imageToProcess[pixelRow, pixelColumn] == 0:
                randomBits = randomBits + "0"#Adds a 0 to the randomBits variable if the current pixel is white
            else:
                randomBits = randomBits + "1"#Adds a 1 to the randomBits variable if the current pixel is black
            pixelColumn = pixelColumn + 1
        pixelRow = pixelRow + 1
        pixelColumn = 0
    output = open('output.txt', 'w')
    output.write(str(int(randomBits, 2)))#Writes the randomBits Variable to the output file converted to a decimal number
    print int(randomBits, 2)#Also prints this decimal number to the terminal
    output.close()