diff --git a/libmeterfeeder.dylib b/libmeterfeeder.dylib new file mode 100755 index 0000000..efc69b6 Binary files /dev/null and b/libmeterfeeder.dylib differ diff --git a/libmeterfeeder.so b/libmeterfeeder.so new file mode 100644 index 0000000..7b1073e Binary files /dev/null and b/libmeterfeeder.so differ diff --git a/libqwqng-wrapper-x86-64.so b/libqwqng-wrapper-x86-64.so deleted file mode 100644 index 9387df6..0000000 Binary files a/libqwqng-wrapper-x86-64.so and /dev/null differ diff --git a/libqwqng-wrapper.so b/libqwqng-wrapper.so deleted file mode 100644 index 5f31175..0000000 Binary files a/libqwqng-wrapper.so and /dev/null differ diff --git a/meterfeeder.dll b/meterfeeder.dll new file mode 100644 index 0000000..3bdb168 Binary files /dev/null and b/meterfeeder.dll differ diff --git a/quanttp/__main__.py b/quanttp/__main__.py index 6f8e5d8..895559f 100644 --- a/quanttp/__main__.py +++ b/quanttp/__main__.py @@ -1,5 +1,6 @@ # Copyright (c) 2020 Andika Wasisto # Modified by Tobias Raayoni Last +# Modified by soliax # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -32,13 +33,12 @@ from flask_sockets import Sockets from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler -from quanttp.data.qng_wrapper_linux import QngWrapperLinux -from quanttp.data.qng_wrapper_windows import QngWrapperWindows +from quanttp.data.meterfeeder_wrapper import MeterFeederWrapper app = Flask(__name__) sockets = Sockets(app) -qng_wrapper = QngWrapperWindows() if (os.name == 'nt') else QngWrapperLinux() +mf_wrapper = MeterFeederWrapper() def main(): # Commandline Arguments (servername, port) @@ -53,49 +53,65 @@ def main(): servername = sys.argv[1] port = int(sys.argv[2]) ip = requests.get('https://api.ipify.org').text - id = str(qng_wrapper.deviceId()) + id = str(mf_wrapper.deviceIds(False)) print("----------------------------------------------------------------------------------------") print("Serving Entropy from TRNG ", id, " as pod \"", servername, "\" on http://", ip, ":", port, "/api/...", sep='') print("----------------------------------------------------------------------------------------") - register = requests.post('https://webhook.site/02e1d079-ab19-4e29-9e13-1aacb17161ad', data = {'name': servername, 'device': id, 'ip': ip, 'port': port }) - print(register) serve(servername, port, id) def serve(servername, port, id): # Original API ---------------------------------------------- + @app.route('/api/devices') + def devices(): + devices = str(mf_wrapper.deviceIds(False)) + return Response(devices, content_type='text/plain') + @app.route('/api/randint32') def randint32(): - return Response(str(qng_wrapper.randint32()), content_type='text/plain') - + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') + return Response(str(mf_wrapper.randint32(deviceId)), content_type='text/plain') @app.route('/api/randuniform') def randuniform(): - return Response(str(qng_wrapper.randuniform()), content_type='text/plain') - + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') + return Response(str(mf_wrapper.randuniform(deviceId)), content_type='text/plain') @app.route('/api/randnormal') def randnormal(): - return Response(str(qng_wrapper.randnormal()), content_type='text/plain') + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') + return Response(str(mf_wrapper.randnormal(deviceId)), content_type='text/plain') @app.route('/api/randhex') def randhex(): try: + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') length = int(request.args.get('length')) if length < 1: return Response('length must be greater than 0', status=400, content_type='text/plain') - return Response(qng_wrapper.randbytes(length).hex(), content_type='text/plain') + return Response(mf_wrapper.randbytes(deviceId, length).hex(), content_type='text/plain') except (TypeError, ValueError) as e: return Response(str(e), status=400, content_type='text/plain') @app.route('/api/randbase64') def randbase64(): try: + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') length = int(request.args.get('length')) if length < 1: return Response('length must be greater than 0', status=400, content_type='text/plain') - return Response(base64.b64encode(qng_wrapper.randbytes(length)).decode('utf-8'), content_type='text/plain') + return Response(base64.b64encode(mf_wrapper.randbytes(deviceId, length)).decode('utf-8'), content_type='text/plain') except (TypeError, ValueError) as e: return Response(str(e), status=400, content_type='text/plain') @@ -103,109 +119,135 @@ def serve(servername, port, id): @app.route('/api/randbytes') def randbytes(): try: + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') length = int(request.args.get('length')) if length < 1: return Response('length must be greater than 0', status=400, content_type='text/plain') - return Response(qng_wrapper.randbytes(length), content_type='application/octet-stream') + return Response(mf_wrapper.randbytes(deviceId, length), content_type='application/octet-stream') except (TypeError, ValueError) as e: return Response(str(e), status=400, content_type='text/plain') @app.route('/api/clear') def clear(): - qng_wrapper.clear() + deviceId = request.args.get('deviceId') + if len(deviceId) != 8: + return Response('deviceId must be a valid 8 character serial number', status=400, content_type='text/plain') + mf_wrapper.clear(deviceId) return Response(status=204) @app.route('/api/reset') def reset(): - qng_wrapper.reset() + mf_wrapper.reset() return Response(status=204) @app.route('/api/status') - def statusstring(): - status = str(qng_wrapper.statusString()) - return Response(json.dumps({"server" : servername, "device": id, "status": status}), status=400, content_type='text/plain') + def status(): + status = "online" # TODO implement me + return Response(json.dumps({"server" : servername, "devices": id, "status": status}), status=400, content_type='text/plain') # JSON API ---------------------------------------------- + @app.route('/api/json/devices') + def devicesjson(): + devices = str(mf_wrapper.deviceIds(True)) + return Response(json.dumps(devices), content_type='application/json') + @app.route('/api/json/randint32') def randjsonint32(): try: - status = str(qng_wrapper.statusString()) + deviceId = request.args.get('deviceId') + 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') + status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') int32array = [] for x in range(0, length): - int32array.append(qng_wrapper.randint32()) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "int32", "length":length, "data": int32array, "success": "true"}), content_type='text/plain') + 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') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "status": status, "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": str(e), "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randuniform') def randjsonuniform(): try: - status = str(qng_wrapper.statusString()) + deviceId = request.args.get('deviceId') + 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') + status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') uniformarray = [] for x in range(0, length): - uniformarray.append(qng_wrapper.randuniform()) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "uniform", "length":length, "data": uniformarray, "success": "true"}), content_type='text/plain') + 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') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randnormal') def randjsonnormal(): try: - status = str(qng_wrapper.statusString()) + deviceId = request.args.get('deviceId') + 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') + status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') normarray = [] for x in range(0, length): - normarray.append(qng_wrapper.randnormal()) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "normal", "length":length, "data": normarray, "success": "true"}), content_type='text/plain') + 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') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randhex') def randjsonhex(): try: - status = str(qng_wrapper.statusString()) + deviceId = request.args.get('deviceId') + 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') + status = str(mf_wrapper.status()) length = int(request.args.get('length')) size = int(request.args.get('size')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') if size < 1: - return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='text/plain') -# entropy = qng_wrapper.randbytes(size*length) + 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) hexarray = [] for x in range(0, length): - hexarray.append(qng_wrapper.randbytes(size).hex()) + hexarray.append(mf_wrapper.randbytes(deviceId, 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='text/plain') + 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: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randbase64') def randjsonbase64(): try: - status = str(qng_wrapper.statusString()) + deviceId = request.args.get('deviceId') + 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') + status = str(mf_wrapper.status()) length = int(request.args.get('length')) size = int(request.args.get('size')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') if size < 1: - return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='text/plain') -# entropy = qng_wrapper.randbytes(size*length) + 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) basearray = [] for x in range(0, length): - basearray.append(base64.b64encode(qng_wrapper.randbytes(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')) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "base64", "length":length, "size": size, "data": basearray, "success": "true"}), content_type='text/plain') + 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: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='text/plain') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') # Websockets ---------------------------------------------- @@ -220,31 +262,31 @@ def serve(servername, port, id): try: split_message = message.strip().upper().split() if split_message[0] == 'RANDINT32': - websocket.send(str(qng_wrapper.randint32())) + websocket.send(str(mf_wrapper.randint32())) elif split_message[0] == 'RANDUNIFORM': - websocket.send(str(qng_wrapper.randuniform())) + websocket.send(str(mf_wrapper.randuniform())) elif split_message[0] == 'RANDNORMAL': - websocket.send(str(qng_wrapper.randnormal())) + websocket.send(str(mf_wrapper.randnormal())) elif split_message[0] == 'RANDBYTES': length = int(split_message[1]) if length < 1: raise ValueError() - websocket.send(qng_wrapper.randbytes(length)) + websocket.send(mf_wrapper.randbytes(length)) elif split_message[0] == 'SUBSCRIBEINT32': if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(qng_wrapper.randint32())) + websocket.send(str(mf_wrapper.randint32())) elif split_message[0] == 'SUBSCRIBEUNIFORM': if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(qng_wrapper.randuniform())) + websocket.send(str(mf_wrapper.randuniform())) elif split_message[0] == 'SUBSCRIBENORMAL': if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(qng_wrapper.randnormal())) + websocket.send(str(mf_wrapper.randnormal())) elif split_message[0] == 'SUBSCRIBEBYTES': chunk = int(split_message[1]) if chunk < 1: @@ -252,7 +294,7 @@ def serve(servername, port, id): if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(qng_wrapper.randbytes(chunk)) + websocket.send(mf_wrapper.randbytes(chunk)) elif split_message[0] == 'SUBSCRIBEHEX': chunk = int(split_message[1]) if chunk < 1: @@ -260,12 +302,12 @@ def serve(servername, port, id): if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(qng_wrapper.randbytes(chunk).hex()) + websocket.send(mf_wrapper.randbytes(chunk).hex()) elif split_message[0] == 'UNSUBSCRIBE': subscribed[0] = False websocket.send('UNSUBSCRIBED') elif split_message[0] == 'CLEAR': - qng_wrapper.clear() + mf_wrapper.clear() except (IndexError, ValueError, BlockingIOError): pass except Exception as e: diff --git a/quanttp/data/meterfeeder_wrapper.py b/quanttp/data/meterfeeder_wrapper.py new file mode 100644 index 0000000..0b446b9 --- /dev/null +++ b/quanttp/data/meterfeeder_wrapper.py @@ -0,0 +1,121 @@ +## + # MeterFeeder Library Wrapper + # + # by soliax + ## + +from platform import os +from sys import platform +from ctypes import * + +cdll = LibraryLoader(CDLL) + +class MeterFeederWrapper: + + def __init__(self): + if platform == "linux" or platform == "linux2": + # Linux + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.so') + elif platform == "darwin": + # OS X + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.dylib') + elif platform == "win32": + # Windows + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/meterfeeder.dll') + + # Declare function bridging + self._meterfeeder.MF_Initialize.argtypes = c_char_p, + self._meterfeeder.MF_Initialize.restype = c_int + + self._meterfeeder.MF_GetNumberGenerators.restype = c_int + + self._meterfeeder.MF_GetListGenerators.argtypes = [POINTER(c_char_p)] + + self._meterfeeder.MF_GetBytes.argtypes = c_int, POINTER(c_ubyte), c_char_p, c_char_p, + + self._meterfeeder.MF_RandInt32.argtypes = c_char_p, c_char_p, + self._meterfeeder.MF_RandInt32.restype = c_int + + self._meterfeeder.MF_RandUniform.argtypes = c_char_p, c_char_p, + self._meterfeeder.MF_RandUniform.restype = c_double + + self._meterfeeder.MF_RandNormal.argtypes = c_char_p, c_char_p, + self._meterfeeder.MF_RandNormal.restype = c_double + + self._meterfeeder.MF_Clear.argtypes = c_char_p, c_char_p, + self._meterfeeder.MF_Clear.restype = c_bool + + self._meterfeeder.MF_Reset.argtypes = c_char_p, + self._meterfeeder.MF_Reset.restype = c_int + + self._medErrorReason = create_string_buffer(256) + + # Initialize Meter Feeder + result = self._meterfeeder.MF_Initialize(self._medErrorReason) + if (len(self._medErrorReason.value) > 0): + print(self._medErrorReason) + exit(result) + + def deviceIds(self, returnAsList): + # Get the list of connected devices + numGenerators = self._meterfeeder.MF_GetNumberGenerators() + generatorsListBuffers = [create_string_buffer(58) for i in range(numGenerators)] + generatorsListBufferPointers = (c_char_p*numGenerators)(*map(addressof, generatorsListBuffers)) + self._meterfeeder.MF_GetListGenerators(generatorsListBufferPointers) + generatorsList = [str(s.value, 'utf-8') for s in generatorsListBuffers] + + if returnAsList: + return generatorsList + + deviceIdsCsvList = "" + for i in range(numGenerators): + if i < numGenerators - 1: + deviceIdsCsvList += generatorsList[i].split("|")[0] + "," + else: + deviceIdsCsvList += generatorsList[i].split("|")[0] + return deviceIdsCsvList + + def randint32(self, deviceId): + try: + return self._meterfeeder.MF_RandInt32(deviceId.encode("utf-8"), self._medErrorReason) + except: + self._meterfeeder.MF_Reset() + return self._meterfeeder.MF_RandInt32(deviceId.encode("utf-8"), self._medErrorReason) + + def randuniform(self, deviceId): + try: + return self._meterfeeder.MF_RandUniform(deviceId.encode("utf-8"), self._medErrorReason) + except: + self._meterfeeder.MF_Reset() + return self._meterfeeder.MF_RandUniform(deviceId.encode("utf-8"), self._medErrorReason) + + def randnormal(self, deviceId): + try: + return self._meterfeeder.MF_RandNormal(deviceId.encode("utf-8"), self._medErrorReason) + except: + self._meterfeeder.MF_Reset() + return self._meterfeeder.MF_RandNormal(deviceId.encode("utf-8"), self._medErrorReason) + + def randbytes(self, deviceId, length): + barray = bytearray(length) + ubuffer = (c_ubyte * length).from_buffer(barray) + try: + self._meterfeeder.MF_GetBytes(length, ubuffer, deviceId.encode("utf-8"), self._medErrorReason) + return barray + except: + self._meterfeeder.MF_Reset() + self._meterfeeder.MF_GetBytes(length, ubuffer, deviceId.encode("utf-8"), self._medErrorReason) + return barray + + def clear(self, deviceId): + if self._meterfeeder.MF_Clear(deviceId.encode("utf-8"), self._medErrorReason) == False: + print("unable to clear", deviceId, ": ", self._medErrorReason.value) + + def reset(self): + result = self._meterfeeder.MF_Reset(self._medErrorReason) + if (len(self._medErrorReason.value) > 0): + print(self._medErrorReason) + exit(result) + + def status(self): + return "ONLINE" diff --git a/quanttp/data/qng_wrapper_linux.py b/quanttp/data/qng_wrapper_linux.py deleted file mode 100644 index f22eb40..0000000 --- a/quanttp/data/qng_wrapper_linux.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2020 Andika Wasisto -# -# 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. - -import platform -from ctypes import cdll, c_void_p, c_int, c_double, POINTER, c_char, c_char_p, cast - - -class QngWrapperLinux: - - def __init__(self): - self._qwqng_wrapper = cdll.LoadLibrary('./libqwqng-wrapper-x86-64.so' if platform.machine().endswith('64') else './libqwqng-wrapper.so') - self._qwqng_wrapper.GetQwqngInstance.restype = c_void_p - self._qwqng_wrapper.RandInt32.argtypes = [c_void_p] - self._qwqng_wrapper.RandInt32.restype = c_int - self._qwqng_wrapper.RandUniform.argtypes = [c_void_p] - self._qwqng_wrapper.RandUniform.restype = c_double - self._qwqng_wrapper.RandNormal.argtypes = [c_void_p] - self._qwqng_wrapper.RandNormal.restype = c_double - self._qwqng_wrapper.RandBytes.argtypes = [c_void_p, c_int] - self._qwqng_wrapper.RandBytes.restype = POINTER(c_char) - self._qwqng_wrapper.StatusString.argtypes = [c_void_p] - self._qwqng_wrapper.StatusString.restype = POINTER(c_char) - self._qwqng_wrapper.DeviceID.argtypes = [c_void_p] - self._qwqng_wrapper.DeviceID.restype = POINTER(c_char) - self._qwqng_wrapper.Clear.argtypes = [c_void_p] - self._qwqng_wrapper.Reset.argtypes = [c_void_p] - self._qng_pointer = self._qwqng_wrapper.GetQwqngInstance() - - def deviceId(self): - try: - return cast(self._qwqng_wrapper.DeviceID(self._qng_pointer), c_char_p).value.decode("utf-8") - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return cast(self._qwqng_wrapper.DeviceID(self._qng_pointer), c_char_p).value.decode("utf-8") - - def statusString(self): - try: - return cast(self._qwqng_wrapper.StatusString(self._qng_pointer), c_char_p).value.decode("utf-8") - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return cast(self._qwqng_wrapper.StatusString(self._qng_pointer), c_char_p).value.decode("utf-8") - - def randint32(self): - try: - return self._qwqng_wrapper.RandInt32(self._qng_pointer) - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return self._qwqng_wrapper.RandInt32(self._qng_pointer) - - def randuniform(self): - try: - return self._qwqng_wrapper.RandUniform(self._qng_pointer) - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return self._qwqng_wrapper.RandUniform(self._qng_pointer) - - def randnormal(self): - try: - return self._qwqng_wrapper.RandNormal(self._qng_pointer) - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return self._qwqng_wrapper.RandNormal(self._qng_pointer) - - def randbytes(self, length): - try: - return self._randbytes_arbitrary_length(length) - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - return self._randbytes_arbitrary_length(length) - - def _randbytes_arbitrary_length(self, length): - try: - return self._qwqng_wrapper.RandBytes(self._qng_pointer, length)[:length] - except: - self._qwqng_wrapper.Reset(self._qng_pointer) - - def clear(self): - self._qwqng_wrapper.Clear(self._qng_pointer) - - def reset(self): - self._qwqng_wrapper.Reset(self._qng_pointer) - diff --git a/quanttp/data/qng_wrapper_mock.py b/quanttp/data/qng_wrapper_mock.py deleted file mode 100644 index 4bcf8b5..0000000 --- a/quanttp/data/qng_wrapper_mock.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2020 Andika Wasisto -# -# 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. - -import random -import secrets - - -class QngWrapperMock: - - def randint32(self): - return random.randint(-2147483648, +2147483647) - - def randuniform(self): - return random.random() - - def randnormal(self): - return random.gauss(mu=0.0, sigma=1.0) - - def randbytes(self, length): - return secrets.token_bytes(nbytes=length) - - def clear(self): - pass \ No newline at end of file diff --git a/quanttp/data/qng_wrapper_windows.py b/quanttp/data/qng_wrapper_windows.py deleted file mode 100644 index aff194d..0000000 --- a/quanttp/data/qng_wrapper_windows.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2020 Andika Wasisto -# -# 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. - - -class QngWrapperWindows: - - def __init__(self): - import win32com.client - self._qng = win32com.client.Dispatch("QWQNG.QNG") - - def deviceId(self): - try: - return self._qng.DeviceId - except: - self._qng.Reset() - return self._qng.DeviceId - - def randint32(self): - try: - return self._qng.RandInt32 - except: - self._qng.Reset() - return self._qng.RandInt32 - - def randuniform(self): - try: - return self._qng.RandUniform - except: - self._qng.Reset() - return self._qng.RandUniform - - def randnormal(self): - try: - return self._qng.RandNormal - except: - self._qng.Reset() - return self._qng.RandNormal - - def randbytes(self, length): - try: - return self._randbytes_arbitrary_length(length) - except: - self._qng.Reset() - return self._randbytes_arbitrary_length(length) - - def _randbytes_arbitrary_length(self, length): - if length <= 8192: - return bytes(self._qng.RandBytes(length)) - else: - data = bytearray() - for x in range(length // 8192): - data.extend(bytearray(self._qng.RandBytes(8192))) - bytes_needed = length % 8192 - if bytes_needed != 0: - data.extend(bytearray(self._qng.RandBytes(bytes_needed))) - return bytes(data) - - def clear(self): - self._qng.Clear() diff --git a/requirements.txt b/requirements.txt index 4f072ce..99e8cd2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ -Flask==1.1.2 +Flask==2.0.1 Flask-Sockets==0.2.1 -gevent==20.5.0 +gevent==21.1.2 gevent-websocket==0.10.1 -pywin32==227; platform_system == 'Windows' +pywin32==301; platform_system == 'Windows' +requests==2.25.1