Compare commits

...

10 commits

Author SHA1 Message Date
randogoth
009f0736b3 updated 2023-05-28 17:48:05 +03:00
randogoth
956de4527f vscode 2023-05-28 16:31:48 +03:00
randogoth
249de6f98d ignore VS stuff 2023-05-28 16:31:31 +03:00
randogoth
6d4b8c8e86 metefeeder submodule 2023-05-28 16:19:30 +03:00
randogoth
d4acf64815 MeterFeeder as submodule 2023-05-28 16:19:27 +03:00
randogoth
05b0da388d
Update README.md 2023-05-28 15:53:40 +03:00
randogoth
b3b12b5bcc
Update README.md
renamed
2023-05-28 15:45:08 +03:00
Randonauts Co
3052b46d77
Merge pull request #2 from Taha-Firoz/Patch
Fixed success type to boolean
2022-01-04 18:43:21 +00:00
Mohammad Taha Bin Firoz
bd9df52b3e fixed to boolean type 2022-01-04 17:17:56 +00:00
Simon Nishi McCorkindale
8bf5b4bbda Update WebSockets API to MeterFeeder (untested) 2021-06-05 21:39:39 +08:00
11 changed files with 89 additions and 51 deletions

5
.gitignore vendored
View file

@ -1,3 +1,6 @@
__pycache__/ __pycache__/
*.iml *.iml
.idea/ .idea/
.venv/
.vscode/
debug.log

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "MeterFeeder"]
path = MeterFeeder
url = git@github.com:TheRandonauts/MeterFeeder.git
shallow = true

View file

@ -1,6 +1,8 @@
MIT License MIT License
Copyright (c) 2020 Andika Wasisto Copyright (c) 2020 Andika Wasisto
Modified by randogoth / Randonauts Co.
Modified by soliax / fp2.dev
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

1
MeterFeeder Submodule

@ -0,0 +1 @@
Subproject commit 6b8de4bd2c8fc0c483c1988b1d99694d8ad31d8d

View file

@ -1,9 +1,9 @@
Pod Entropy Server Quanttp 2 Entropy Server
================== ========================
_based on [quanttp](https://github.com/awasisto/quanttp) by [Andika Wasisto](https://www.wasisto.com/)_ _based on [quanttp](https://github.com/awasisto/quanttp) by [Andika Wasisto](https://www.wasisto.com/)_
An HTTP API that wraps [ComScire quantum random number generator API](https://comscire.com/downloads/qwqngdoc/). An HTTP API that wraps [MeterFeeder](https://github.com/TheRandonauts/MeterFeeder) instead of the [ComScire quantum random number generator API](https://comscire.com/downloads/qwqngdoc/) to support serving entropy from multiple devices. It also adds JSON endpoints.
Running Running
------- -------
@ -37,9 +37,6 @@ Usage Example
### REST JSON API ### REST JSON API
http://localhost:<port>/api/json/randint32?length=3&deviceId=QWR4E001
< {"devices":['QWR4E002|MED100KX8 100 kHz', 'QWR4E001|MED100KX8 100 kHz']}
http://localhost:<port>/api/json/randint32?length=3&deviceId=QWR4E001 http://localhost:<port>/api/json/randint32?length=3&deviceId=QWR4E001
< {"server": "<servername>", "type": "string", "format": "int32", "length": 3, "data": [1524492492, -1194151004, 1365408501], "success": "true"} < {"server": "<servername>", "type": "string", "format": "int32", "length": 3, "data": [1524492492, -1194151004, 1365408501], "success": "true"}
@ -103,7 +100,7 @@ License
------- -------
Copyright (c) 2020 Andika Wasisto Copyright (c) 2020 Andika Wasisto
Modified by Tobias Raayoni Last / Randonauts Co. Modified by randogoth / Randonauts Co.
Modified by soliax / fp2.dev Modified by soliax / fp2.dev
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
@ -122,4 +119,4 @@ License
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View file

@ -1 +0,0 @@
[0917/192900.742:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,5 @@
# Copyright (c) 2020 Andika Wasisto # Copyright (c) 2020 Andika Wasisto
# Modified by Tobias Raayoni Last # Modified by randogoth
# Modified by soliax # Modified by soliax
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
@ -159,95 +159,95 @@ def serve(servername, port, id):
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: if len(deviceId) != 8:
return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json')
status = str(mf_wrapper.status()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: if length < 1:
return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json')
int32array = [] int32array = []
for x in range(0, length): for x in range(0, length):
int32array.append(mf_wrapper.randint32(deviceId)) int32array.append(mf_wrapper.randint32(deviceId))
return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "int32", "length":length, "data": int32array, "success": "true"}), content_type='application/json') return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "int32", "length":length, "data": int32array, "success":True}), content_type='application/json')
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
return Response(json.dumps({"error": str(e), "status": status, "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": str(e), "status": status, "success":False}), status=400, content_type='application/json')
@app.route('/api/json/randuniform') @app.route('/api/json/randuniform')
def randjsonuniform(): def randjsonuniform():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: if len(deviceId) != 8:
return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json')
status = str(mf_wrapper.status()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: if length < 1:
return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json')
uniformarray = [] uniformarray = []
for x in range(0, length): for x in range(0, length):
uniformarray.append(mf_wrapper.randuniform(deviceId)) uniformarray.append(mf_wrapper.randuniform(deviceId))
return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "uniform", "length":length, "data": uniformarray, "success": "true"}), content_type='application/json') return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "uniform", "length":length, "data": uniformarray, "success":True}), content_type='application/json')
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json')
@app.route('/api/json/randnormal') @app.route('/api/json/randnormal')
def randjsonnormal(): def randjsonnormal():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: if len(deviceId) != 8:
return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json')
status = str(mf_wrapper.status()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: if length < 1:
return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json')
normarray = [] normarray = []
for x in range(0, length): for x in range(0, length):
normarray.append(mf_wrapper.randnormal(deviceId)) normarray.append(mf_wrapper.randnormal(deviceId))
return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "normal", "length":length, "data": normarray, "success": "true"}), content_type='application/json') return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "normal", "length":length, "data": normarray, "success":True}), content_type='application/json')
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json')
@app.route('/api/json/randhex') @app.route('/api/json/randhex')
def randjsonhex(): def randjsonhex():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: if len(deviceId) != 8:
return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json')
status = str(mf_wrapper.status()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
size = int(request.args.get('size')) size = int(request.args.get('size'))
if length < 1: if length < 1:
return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json')
if size < 1: if size < 1:
return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'size must be greater than 0', "success":False}), status=400, content_type='application/json')
# entropy = mf_wrapper.randbytes(size*length) # entropy = mf_wrapper.randbytes(size*length)
hexarray = [] hexarray = []
for x in range(0, length): for x in range(0, length):
hexarray.append(mf_wrapper.randbytes(deviceId, size).hex()) hexarray.append(mf_wrapper.randbytes(deviceId, size).hex())
# hexarray.append(entropy[x*size:(x+1)*size].hex()) # hexarray.append(entropy[x*size:(x+1)*size].hex())
return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "hex", "length":length, "size": size, "data": hexarray, "success": "true"}), content_type='application/json') return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "hex", "length":length, "size": size, "data": hexarray, "success":True}), content_type='application/json')
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json')
@app.route('/api/json/randbase64') @app.route('/api/json/randbase64')
def randjsonbase64(): def randjsonbase64():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: if len(deviceId) != 8:
return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json')
status = str(mf_wrapper.status()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
size = int(request.args.get('size')) size = int(request.args.get('size'))
if length < 1: if length < 1:
return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json')
if size < 1: if size < 1:
return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": 'size must be greater than 0', "success":False}), status=400, content_type='application/json')
# entropy = mf_wrapper.randbytes(size*length) # entropy = mf_wrapper.randbytes(size*length)
basearray = [] basearray = []
for x in range(0, length): for x in range(0, length):
basearray.append(base64.b64encode(mf_wrapper.randbytes(deviceId, size)).decode('utf-8')) basearray.append(base64.b64encode(mf_wrapper.randbytes(deviceId, size)).decode('utf-8'))
# basearray.append(base64.b64encode(entropy[x*size:(x+1)*size]).decode('utf-8')) # basearray.append(base64.b64encode(entropy[x*size:(x+1)*size]).decode('utf-8'))
return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "base64", "length":length, "size": size, "data": basearray, "success": "true"}), content_type='application/json') return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "base64", "length":length, "size": size, "data": basearray, "success":True}), content_type='application/json')
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json')
# Websockets ---------------------------------------------- # Websockets ----------------------------------------------
@ -261,53 +261,85 @@ def serve(servername, port, id):
def handle_ws_message(message, websocket, subscribed): def handle_ws_message(message, websocket, subscribed):
try: try:
split_message = message.strip().upper().split() split_message = message.strip().upper().split()
if split_message[0] == 'RANDINT32': if split_message[0] == 'DEVICES':
websocket.send(str(mf_wrapper.randint32())) websocket.send(str(mf_wrapper.deviceIds(False)))
elif split_message[0] == 'RANDINT32':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
websocket.send(str(mf_wrapper.randint32(deviceId)))
elif split_message[0] == 'RANDUNIFORM': elif split_message[0] == 'RANDUNIFORM':
websocket.send(str(mf_wrapper.randuniform())) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
websocket.send(str(mf_wrapper.randuniform(deviceId)))
elif split_message[0] == 'RANDNORMAL': elif split_message[0] == 'RANDNORMAL':
websocket.send(str(mf_wrapper.randnormal())) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
websocket.send(str(mf_wrapper.randnormal(deviceId)))
elif split_message[0] == 'RANDBYTES': elif split_message[0] == 'RANDBYTES':
length = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
length = int(split_message[2])
if length < 1: if length < 1:
raise ValueError() raise ValueError()
websocket.send(mf_wrapper.randbytes(length)) websocket.send(mf_wrapper.randbytes(deviceId, length))
elif split_message[0] == 'SUBSCRIBEINT32': elif split_message[0] == 'SUBSCRIBEINT32':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randint32())) websocket.send(str(mf_wrapper.randint32(deviceId)))
elif split_message[0] == 'SUBSCRIBEUNIFORM': elif split_message[0] == 'SUBSCRIBEUNIFORM':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randuniform())) websocket.send(str(mf_wrapper.randuniform(deviceId)))
elif split_message[0] == 'SUBSCRIBENORMAL': elif split_message[0] == 'SUBSCRIBENORMAL':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randnormal())) websocket.send(str(mf_wrapper.randnormal(deviceId)))
elif split_message[0] == 'SUBSCRIBEBYTES': elif split_message[0] == 'SUBSCRIBEBYTES':
chunk = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
chunk = int(split_message[2])
if chunk < 1: if chunk < 1:
raise ValueError() raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(mf_wrapper.randbytes(chunk)) websocket.send(mf_wrapper.randbytes(deviceId, chunk))
elif split_message[0] == 'SUBSCRIBEHEX': elif split_message[0] == 'SUBSCRIBEHEX':
chunk = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
chunk = int(split_message[2])
if chunk < 1: if chunk < 1:
raise ValueError() raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(mf_wrapper.randbytes(chunk).hex()) websocket.send(mf_wrapper.randbytes(deviceId, chunk).hex())
elif split_message[0] == 'UNSUBSCRIBE': elif split_message[0] == 'UNSUBSCRIBE':
subscribed[0] = False subscribed[0] = False
websocket.send('UNSUBSCRIBED') websocket.send('UNSUBSCRIBED')
elif split_message[0] == 'CLEAR': elif split_message[0] == 'CLEAR':
mf_wrapper.clear() deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
mf_wrapper.clear(deviceId)
except (IndexError, ValueError, BlockingIOError): except (IndexError, ValueError, BlockingIOError):
pass pass
except Exception as e: except Exception as e:

View file

@ -1,7 +1,7 @@
## ##
# MeterFeeder Library Wrapper # MeterFeeder Library Wrapper
# #
# by soliax # by soliax, randogoth
## ##
from platform import os from platform import os
@ -15,13 +15,13 @@ class MeterFeederWrapper:
def __init__(self): def __init__(self):
if platform == "linux" or platform == "linux2": if platform == "linux" or platform == "linux2":
# Linux # Linux
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.so') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/linux/libmeterfeeder.so')
elif platform == "darwin": elif platform == "darwin":
# OS X # OS X
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.dylib') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/mac/libmeterfeeder.dylib')
elif platform == "win32": elif platform == "win32":
# Windows # Windows
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/meterfeeder.dll') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/windows/meterfeeder.dll')
# Declare function bridging # Declare function bridging
self._meterfeeder.MF_Initialize.argtypes = c_char_p, self._meterfeeder.MF_Initialize.argtypes = c_char_p,