175 lines
4.4 KiB
Python
175 lines
4.4 KiB
Python
|
|
#!/usr/bin/python
|
|
|
|
# TrueRNG Read - Simple Example
|
|
# Chris K Cockrum
|
|
# 7/9/2021
|
|
#
|
|
# Requires Python 2.7 or 3.7+, pyserial
|
|
# On Linux - may need to be root or set /dev/tty port permissions to 666
|
|
#
|
|
# Python available here: https://www.python.org/
|
|
# Install Pyserial package with: python -m pip install pyserial
|
|
|
|
import serial
|
|
import time
|
|
import os
|
|
from serial.tools import list_ports
|
|
|
|
# Number of Bytes to Capture per Block
|
|
blocksize=1024
|
|
|
|
# Number of Blocks to Capture
|
|
numloops=1024
|
|
|
|
# Print our header
|
|
print('TrueRNG Counting Ones vs Zeros Example')
|
|
print('http://ubld.it')
|
|
print('==================================================')
|
|
|
|
import serial.tools.list_ports
|
|
|
|
# ubld.it TrueRNG
|
|
TrueRNGpid="04D8"
|
|
TrueRNGhid="F5FE"
|
|
|
|
# ubld.it TrueRNGpro
|
|
TrueRNGpropid="16D0"
|
|
TrueRNGprohid="0AA0"
|
|
|
|
# ubld.it TrueRNGproV2
|
|
TrueRNGproV2pid="04D8"
|
|
TrueRNGproV2hid="EBB5"
|
|
|
|
# Set default of None for com port
|
|
rng_com_port = None
|
|
|
|
ports = list(serial.tools.list_ports.comports())
|
|
|
|
for p in ports:
|
|
if(rng_com_port == None):
|
|
if TrueRNGproV2pid and TrueRNGproV2hid in p.hwid:
|
|
rng_com_port = p.device
|
|
print('TrueRNGproV2 Found')
|
|
break
|
|
if TrueRNGpropid and TrueRNGprohid in p.hwid:
|
|
rng_com_port = p.device
|
|
print('TrueRNGpro Found')
|
|
break
|
|
if TrueRNGpid and TrueRNGhid in p.hwid:
|
|
rng_com_port = p.device
|
|
print('TrueRNG Found')
|
|
break
|
|
|
|
if rng_com_port == None:
|
|
print('TrueRNG Not Found')
|
|
exit()
|
|
|
|
# Print which port we're using
|
|
print('Using com port: ' + str(rng_com_port))
|
|
|
|
# Print block size and number of loops
|
|
print('Block Size: ' + str(blocksize) + ' Bytes')
|
|
print('Number of loops: ' + str(numloops))
|
|
print('Total size: ' + str(blocksize * numloops) + ' Bytes')
|
|
print('Writing to: random.bin')
|
|
print('==================================================')
|
|
|
|
# Open/create the file random.bin in the current directory with 'write binary'
|
|
fp=open('random.bin','wb')
|
|
|
|
# Print an error if we can't open the file
|
|
if fp==None:
|
|
print('Error Opening File!')
|
|
|
|
# Try to setup and open the comport
|
|
try:
|
|
ser = serial.Serial(port=rng_com_port,timeout=10) # timeout set at 10 seconds in case the read fails
|
|
except:
|
|
print('Port Not Usable!')
|
|
print('Do you have permissions set to read ' + rng_com_port + ' ?')
|
|
|
|
# Open the serial port if it isn't open
|
|
if(ser.isOpen() == False):
|
|
ser.open()
|
|
|
|
# Set Data Terminal Ready to start flow
|
|
ser.setDTR(True)
|
|
|
|
# This clears the receive buffer so we aren't using buffered data
|
|
ser.flushInput()
|
|
|
|
# Keep track of total bytes read
|
|
totalbytes=0
|
|
totalzeros=0
|
|
|
|
# Generate look-up table for number of 1's in a byte
|
|
ones_in_byte = [0] * 256
|
|
for n in range(256):
|
|
ones_in_byte[n] = bin(n).count("1")
|
|
|
|
totalones=0
|
|
totalzeros=0
|
|
|
|
print('Starting data collection...')
|
|
starttime=time.time()
|
|
# Loop
|
|
for _ in range(numloops):
|
|
|
|
# Try to read the port and record the time before and after
|
|
try:
|
|
x=ser.read(blocksize) # read bytes from serial port
|
|
except:
|
|
print('Read Failed!!!')
|
|
break
|
|
|
|
# Update total bytes read
|
|
totalbytes +=len(x)
|
|
|
|
# Count ones
|
|
for n in range(len(x)):
|
|
totalones=totalones + ones_in_byte[x[n]]
|
|
totalzeros=totalzeros + 8-ones_in_byte[x[n]]
|
|
|
|
# If we were able to open the file, write to disk
|
|
if fp !=0:
|
|
fp.write(x)
|
|
|
|
# Calculate the rate
|
|
timenow=time.time()
|
|
if(timenow!=starttime):
|
|
rate=float(totalbytes) / ((timenow-starttime)*1000.0)
|
|
|
|
print(str(totalbytes) + ' Bytes Read at ' + '{:6.2f}'.format(rate) + ' Kbytes/s',end='\r')
|
|
|
|
endtime=time.time()
|
|
total_time = endtime - starttime
|
|
|
|
print('\n\nResults')
|
|
print( '=======')
|
|
print('Total execution time: {:.2f} seconds'.format(total_time))
|
|
print('Total Ones : ' + str(totalones))
|
|
print('Total Zeros: ' + str(totalzeros) + '\n')
|
|
print('Total Bits : ' + str(totalbytes*8))
|
|
|
|
if (totalones==totalzeros):
|
|
print('\nEqual Number of Ones and Zeros in Capture!')
|
|
if (totalones>totalzeros):
|
|
print('\nThere are ' + str(totalones-totalzeros) + ' more ones in the Capture!')
|
|
else:
|
|
print('\nThere are ' + str(totalzeros-totalones) + ' more zeros in the Capture!')
|
|
|
|
print( '=======')
|
|
|
|
# Close the serial port
|
|
ser.close()
|
|
|
|
# If the file is open then close it
|
|
if fp != 0:
|
|
fp.close()
|
|
|
|
# If we're on Linux set min on com port back to 1
|
|
# Pyserial screws this up
|
|
if os.name == 'posix':
|
|
os.system('stty -F '+rng_com_port+' min 1')
|