-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
107 lines (96 loc) · 3.29 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# INFO
# @author: TheCookingSenpai
# @github: https://github.com/TheCookingSenpai
# @homepage: https://github.com/TheCookingSenpai/AmbianceRNG
#
# @description:
# This is a very simple proof of concept for generating true random numbers by
# feeding the python pseudo-random number generator with ambiental noise.
# While is not enforced, the ambiental noise is expected to be generated by
# having an input device that is able to capture sound from the environment.
# A cheap and simple way to generate ambiental noise is to use a simple radio
# with antenna and headphone out and to connect the headphone to your computer.
# Be sure to tune your radio into an empty frequency so that the ambiental
# recording is purely background noise.
#
import pyaudio
import wave
from bitstring import BitArray
import hashlib
import random
class AmbianceRNG:
def __init__(self):
self.CHUNK = 1024
self.FORMAT = pyaudio.paInt16
self.CHANNELS = 1
self.RATE = 44100
self.RECORD_SECONDS = 2
self.WAVE_OUTPUT_FILENAME = "seed.wav"
self.frames = []
self.stream = None
self.device = None
self.bin_bytes = ''
def record_seed(self):
# Opening our device and setting up the stream for recording
self.device = pyaudio.PyAudio()
self.stream = self.device.open(format=self.FORMAT,
channels=self.CHANNELS,
rate=self.RATE,
input=True,
frames_per_buffer=self.CHUNK)
print("* detecting ambiental noise...")
# Recording ambiental noise
for _ in range(int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
data = self.stream.read(self.CHUNK)
self.frames.append(data)
print("* done recording ambiental noise")
self.stream.stop_stream()
self.stream.close()
self.device.terminate()
return self.frames
def save_seed(self):
wf = wave.open(self.WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(self.CHANNELS)
wf.setsampwidth(self.device.get_sample_size(self.FORMAT))
wf.setframerate(self.RATE)
wf.writeframes(b''.join(self.frames))
wf.close()
def serialize_seed(self):
print("* serializing ambiental noise... [ ]", end="\b\b", flush=True)
counter = 1 # Initialized to 1 to avoid unnecessary assignment later
bin_bytes = ''
with open(self.WAVE_OUTPUT_FILENAME, 'rb') as f:
all_bytes = f.read()
raw_bytes = all_bytes[44:] # Removing the first 44 bytes
self.bin_bytes = BitArray(raw_bytes)
print("\b\b\n* done serializing ambiental noise")
# Logging to file
with open("seed.txt", "w") as f:
f.write(str(self.bin_bytes))
def get_random_number(self, min, max):
# Using an hash representation is way faster than using the whole string
hash_object = hashlib.sha256(str(self.bin_bytes).encode())
hex_dig = hash_object.hexdigest()
print(f"* using seed {hex_dig}")
with open("hash.txt", "a") as f:
f.write(f"{hex_dig}\n")
# Seeding the prng
random.seed(hex_dig, version=2)
# Getting a random number
arn = random.randint(min, max)
with open("random.txt", "a+") as f:
f.write(f"{arn} ")
with open("seeds_history.txt", "a+") as f:
f.write(f"{hex_dig}\n")
return arn
if __name__ == "__main__":
counter = 0
while True:
arng = AmbianceRNG()
arng.record_seed()
arng.save_seed()
arng.serialize_seed()
rn = arng.get_random_number(1, 100)
counter += 1
print(f"Produced {counter} random numbers")
print(rn)