mirror of
https://github.com/tcsenpai/VisualRNG.git
synced 2025-06-02 17:30:22 +00:00
Initial commit
This commit is contained in:
commit
758a2e8d1e
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Blockdrops LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
64
README.md
Normal file
64
README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# VisualRNG
|
||||
|
||||

|
||||
|
||||
## What is this
|
||||
|
||||
VisualRNG is a small python implementation of some general considerations about randomness.
|
||||
|
||||
The goal is, of course, obtain true randomness with a cheap, replicable DIY setup.
|
||||
|
||||
## Install and Run
|
||||
|
||||
git clone https://github.com/thecookingsenpai/VisualRNG
|
||||
cd VisualRNG
|
||||
pip install -r requirements.txt
|
||||
python main.py
|
||||
|
||||
Once you have done this, you should have a live API on http://localhost:1122.
|
||||
By visiting the website, you will obtain the random number of that precise frame.
|
||||
|
||||
Feel free to change ports and behaviors directly in main.py.
|
||||
|
||||
## Is this True Randomness? Is this a True Random Number Generator?
|
||||
|
||||
Technically, it could be. The principle is that your randomness is as good as your entropy.
|
||||
Long story short, entropy is the 'seed' that scrambles the algorithm to produce a random number (sorry cypherpunk friends).
|
||||
|
||||
## So what is this?
|
||||
|
||||
This is a software that connect to any video capture device (e.g. a webcam) and produce a random number using the actual frame captured by the device.
|
||||
|
||||
## More in details?
|
||||
|
||||
Let's consider this demo setup:
|
||||
|
||||

|
||||
|
||||
On the right, we have that little white RGB bar: this is a small microphone that react to sounds producing a sort of RGB intensity meter.
|
||||
|
||||
On the left, we have a common lava lamp bought on Amazon.
|
||||
|
||||
The PC I used does not matter, as long as it runs Python 3.8 or higher.
|
||||
|
||||
Highlighted due to the small size, we also have the low quality USB camera looking at us.
|
||||
|
||||
We assume that at any given moment the sound conditions of the environment are unknown, especially if the microphone is high quality. For the same reason, we assume that the lava lamp melted wax moves in an unpredictable way, creating color strikes and light changes. That said, we also know that by itself a low definition USB camera will produce some unpredictable noise.
|
||||
|
||||
See the pattern? We have three strong sources of entropy! But...wouldn't it be complicated to measure all together quickly?
|
||||
|
||||
Well, the trick here is that a video frame contains informations taken from the light surrounding the device capturing it. We are directly converting sound into visuals with the microphone RGB bar, while image noise and lava lamp variations are naturally contained in the video frame.
|
||||
|
||||
By hashing the image, deriving a number from the hash and using it as a seed for our random number generator, we obtain a high quality random number with a cheap DIY setup.
|
||||
|
||||
## Theory summary
|
||||
|
||||
Randomness is as good as the goodness of the below entropy. Entropy is good if it is unpredictable, unreplicable and unknown to third parties. Timestamp is often used as entropy source as it has literally a millisecond of life span.
|
||||
|
||||
Following this reasoning, any unpredictable entropy source that is only observable by the randomness generator should generate true randomness.
|
||||
|
||||
By combining multiple sources of entropy, all highly connected to the local environment and influencing one the other, such as sounds, lights and colors, we obtain a practically unpredictable, unrepicable and highly unstable source of entropy. Combining three different sources also strenghten the resistance of the generator as even the failure of 2 of the 3 sources (e.g. hacked sound card or anything else that breaks up) still offers a reasonable grade of security.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
45
main.py
Normal file
45
main.py
Normal file
@ -0,0 +1,45 @@
|
||||
import cv2
|
||||
import hashlib
|
||||
import re
|
||||
import random
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import FileResponse
|
||||
import uvicorn
|
||||
import time
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
vCapture = cv2.VideoCapture(0)
|
||||
if (vCapture.isOpened() == False):
|
||||
print("Error opening video stream or file")
|
||||
exit()
|
||||
|
||||
# The following method return a number composed from all the digits in a string one after another
|
||||
def get_number(s):
|
||||
ints = re.findall('(\d+)', s)
|
||||
intString = ''.join(ints)
|
||||
return intString
|
||||
|
||||
def vRandGo():
|
||||
global vCapture
|
||||
ret, frame = vCapture.read()
|
||||
hash = hashlib.sha256(frame).hexdigest()
|
||||
print(hash)
|
||||
seed = get_number(hash)
|
||||
print(seed)
|
||||
random.seed(seed)
|
||||
visualrandom = random.randrange(1, 10)
|
||||
print(visualrandom)
|
||||
#cv2.imshow('Video', frame)
|
||||
#if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
# break
|
||||
return {"visualrandom": visualrandom, "seed": seed, "hash": hash, "time": time.time()}
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"rand": vRandGo()}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="0.0.0.0", port=1122)
|
||||
|
||||
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
opencv-python
|
Loading…
x
Reference in New Issue
Block a user