diff --git a/REST/app.py b/REST/app.py
index a830295..afbcbd9 100644
--- a/REST/app.py
+++ b/REST/app.py
@@ -10,54 +10,67 @@ CORS(app)
initialized = False
+def create_response(status_code, description):
+ return jsonify({
+ 'status': status_code,
+ 'description': description
+ })
+
@app.route('/trng/randomNum/init', methods=['GET'])
def initialize_generator():
- global initialized # Zugriff auf die globale Variable
+ global initialized
- #parameter 1 und 2 sind default values für Tests
result = analyze_data(int(1), int(1), startup=True)
if result is True:
initialized = True
- return jsonify({'message': 'successful operation; random number generator is ready and random numbers can be requested'}), 200
+ return create_response(200, 'Successful operation; random number generator is ready and random numbers can be requested')
+ if random_numbers == 400:
+ return create_response(500, 'Tests failed, try again')
+ if random_numbers is False:
+ return create_response(500, 'Unable to generate random numbers. Restart/Reset System')
else:
- return jsonify({'error': 'Unable to initialize the random number generator within a timeout of 60 seconds.'}), 555
+ return create_response(555, 'Unable to initialize the random number generator within a timeout of 60 seconds')
@app.route('/trng/randomNum/getRandom', methods=['GET'])
def get_random_numbers():
- global initialized # Zugriff auf die globale Variable
+ global initialized
quantity = request.args.get('quantity')
bits = request.args.get('numBits')
if not quantity.isdigit() or not bits.isdigit():
- return jsonify({'error': 'Invalid input. Quantity and bits must be numeric.'}), 400
+ return create_response(400, 'Invalid input. Quantity and bits must be numeric.')
if int(quantity) <= 0 or int(bits) <= 0:
- return jsonify({'error': 'Invalid input. Quantity and bits must be positive integers.'}), 400
+ return create_response(400, 'Invalid input. Quantity and bits must be positive integers.')
- # Überprüfe den Initialisierungsstatus
if not initialized:
- return jsonify({'error': 'system not ready; try init'}), 432
+ return create_response(432, 'System not ready; try init')
random_numbers = analyze_data(int(quantity), int(bits), startup=False)
+ if random_numbers == 400:
+ return create_response(500, 'Tests failed, try again')
if random_numbers is False:
- return jsonify({'error': 'Unable to generate random numbers.'}), 500
+ return create_response(500, 'Unable to generate random numbers. Restart/Reset System')
if random_numbers:
- data = {'randomNumbers': random_numbers} # Erstellen des Datenobjekts mit dem JSON-String
- return jsonify(data), 200
+ data = {
+ 'status': 200,
+ 'description': 'Successful operation; HEX-encoded bit arrays (with leading zeros if required)',
+ 'randomNumbers': random_numbers
+ }
+ return jsonify(data)
else:
- return jsonify({'error': 'Unable to generate random numbers.'}), 500
+ return create_response(500, 'Unable to generate random numbers.')
@app.route('/trng/randomNum/shutdown', methods=['GET'])
def shutdown_generator():
- global initialized # Zugriff auf die globale Variable
+ global initialized
- initialized = False # Setze den Initialisierungsstatus zurück
+ initialized = False
- # Beispielantwort
- return jsonify({'message': "successful operation; random number generator has been set to 'standby mode'"}), 200
+ return create_response(200, "Successful operation; random number generator has been set to 'standby mode'")
if __name__ == '__main__':
diff --git a/REST/index.html b/REST/index.html
index f97e053..ddbda3c 100644
--- a/REST/index.html
+++ b/REST/index.html
@@ -1,6 +1,7 @@
+
GMTROM - True Random Number Generator
@@ -11,144 +12,27 @@
+
+
+
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/REST/script.js b/REST/script.js
new file mode 100644
index 0000000..685df19
--- /dev/null
+++ b/REST/script.js
@@ -0,0 +1,236 @@
+// Initialisieren der Eingabefelder
+var quantityInput = document.getElementById('quantity');
+var bitsInput = document.getElementById('bits');
+
+// Deaktivieren der Eingabefelder
+quantityInput.disabled = true;
+bitsInput.disabled = true;
+
+/*------------------------------------------Init Button-----------------------------------------------*/
+document.getElementById('initButton').addEventListener('click', function() {
+
+ //zurücksetzen von status und description
+ document.getElementById('description').innerText = '';
+ document.getElementById('status').innerText = '';
+ document.getElementById('result').innerText = '';
+
+ showLoadingSpinner('Start-up tests and system initialization in progress.');
+
+ fetch('https://172.16.78.57:5000/trng/randomNum/init')
+ .then(response => {
+ document.getElementById('status').innerText = 'Status: ' + response.status;
+ return response.json();
+ })
+ .then(data => {
+ document.getElementById('description').innerText = data.description;
+ console.log('Initialisierung erfolgreich');
+
+ // Deaktiviere Generate und Shutdown Buttons
+ //document.getElementById('generateButton').disabled = false;
+ document.getElementById('shutdownButton').disabled = false;
+ // Aktiviere Initialize Button
+ document.getElementById('initButton').disabled = true;
+
+ // Aktivieren der Eingabefelder
+ quantityInput.disabled = false;
+ bitsInput.disabled = false;
+ })
+ .catch(error => {
+ console.error('Fehler beim Initialisieren:', error);
+ })
+ .finally(() => {
+ hideLoadingSpinner();
+ });
+});
+
+/*------------------------------------------Generate Button-----------------------------------------------*/
+document.getElementById('generateButton').addEventListener('click', function(event) {
+ // Zurücksetzen von status und description
+ document.getElementById('description').innerText = '';
+ document.getElementById('status').innerText = '';
+ document.getElementById('result').innerText = '';
+
+ showLoadingSpinner('Generating and testing random numbers.');
+
+ var quantity = document.getElementById('quantity').value;
+ var bits = document.getElementById('bits').value;
+
+ var url = 'https://172.16.78.57:5000/trng/randomNum/getRandom';
+ if (quantity && bits) {
+ url += '?quantity=' + quantity + '&numBits=' + bits;
+ }
+
+ fetch(url)
+ .then(response => {
+ document.getElementById('status').innerText = 'Status: ' + response.status;
+ return response.json();
+ })
+ .then(data => {
+ document.getElementById('status').innerText = 'Status: ' + data.status;
+ document.getElementById('description').innerText = data.description;
+
+ var resultDiv = document.getElementById('result');
+ resultDiv.innerHTML = ''; // Clear previous results
+
+ if (data.status !== 200) {
+ return;
+ }
+
+ if (data.status === 200) {
+ var table = document.createElement('table');
+ table.classList.add('table');
+ var thead = document.createElement('thead');
+ var tbody = document.createElement('tbody');
+ var trHead = document.createElement('tr');
+ var thNr = document.createElement('th');
+ var thCopy = document.createElement('th');
+ var thRandom = document.createElement('th');
+ var copyAllButton = document.createElement('button');
+
+ thNr.textContent = 'ID';
+ thCopy.textContent = ' ';
+ thRandom.textContent = 'Random Number';
+
+ trHead.appendChild(thNr);
+ trHead.appendChild(thCopy);
+ trHead.appendChild(thRandom);
+ thead.appendChild(trHead);
+ table.appendChild(thead);
+
+ var hexNumbers = JSON.parse(data.randomNumbers); // JSON-Array parsen
+
+ for (var i = 0; i < hexNumbers.length; i++) {
+ var tr = document.createElement('tr');
+ var tdNr = document.createElement('td');
+ var tdCopy = document.createElement('td');
+ var tdRandom = document.createElement('td');
+ var copyButton = document.createElement('button');
+
+ tdNr.textContent = (i + 1).toString();
+ tdRandom.textContent = hexNumbers[i];
+ copyButton.textContent = 'Copy';
+ copyButton.classList.add('copy-button');
+
+ copyButton.addEventListener('click', function() {
+ copyToClipboard(this.parentElement.nextElementSibling.textContent);
+ });
+
+ tdCopy.appendChild(copyButton);
+ tr.appendChild(tdNr);
+ tr.appendChild(tdCopy);
+ tr.appendChild(tdRandom);
+ tbody.appendChild(tr);
+ }
+
+ table.appendChild(tbody);
+ resultDiv.appendChild(table);
+
+ copyAllButton.textContent = 'Copy all';
+ copyAllButton.classList.add('copy-button');
+ copyAllButton.style.marginBottom = '5px'; // Setze den Abstand nach unten
+
+ copyAllButton.addEventListener('click', function() {
+ copyToClipboard(hexNumbers.join('\n'));
+ });
+
+ resultDiv.insertBefore(copyAllButton, table); // Füge den "Copy all" Button vor der Tabelle ein
+ } else {
+ var errorParagraph = document.createElement('p');
+ errorParagraph.textContent = 'Error: ' + data.message;
+ resultDiv.appendChild(errorParagraph);
+ }
+
+ console.log('Generierung erfolgreich');
+ })
+ .catch(error => {
+ console.error('Fehler beim Generieren:', error);
+ })
+ .finally(() => {
+ hideLoadingSpinner();
+ });
+});
+
+/*------------------------------------------Copy to Clipboard-----------------------------------------------*/
+function copyToClipboard(text) {
+ var textArea = document.createElement('textarea');
+ textArea.value = text;
+ document.body.appendChild(textArea);
+ textArea.select();
+ document.execCommand('copy');
+ document.body.removeChild(textArea);
+
+ // Anzeigen eines Popups zur Bestätigung der Kopie
+ window.alert('The text has been copied to the clipboard!');
+}
+
+/*------------------------------------------Shutdown Button-----------------------------------------------*/
+document.getElementById('shutdownButton').addEventListener('click', function() {
+ //zurücksetzen von status und description
+ document.getElementById('description').innerText = '';
+ document.getElementById('status').innerText = '';
+ //textfelder zurücksetzen
+ document.getElementById('quantity').value = '';
+ document.getElementById('bits').value = '';
+ //result div zurücksetzen
+ document.getElementById('result').innerText = '';
+
+ showLoadingSpinner('Shutting down the system.'); // Zeigt den Lade-Spinner
+
+ fetch('https://172.16.78.57:5000/trng/randomNum/shutdown')
+ .then(response => {
+ document.getElementById('status').innerText = 'Status: ' + response.status;
+ return response.json();
+ })
+ .then(data => {
+ document.getElementById('description').innerText = data.description;
+ console.log('Herunterfahren erfolgreich');
+
+ // Deaktiviere Generate und Shutdown Buttons
+ document.getElementById('generateButton').disabled = true;
+ document.getElementById('shutdownButton').disabled = true;
+ // Aktiviere Initialize Button
+ document.getElementById('initButton').disabled = false;
+ })
+ .catch(error => {
+ console.error('Fehler beim Herunterfahren:', error);
+ })
+ .finally(() => {
+ hideLoadingSpinner(); // Blende den Lade-Spinner aus
+ });
+});
+
+// Überprüfungsfunktion für die Eingabefelder
+function checkInputFields() {
+ var quantity = document.getElementById('quantity').value;
+ var bits = document.getElementById('bits').value;
+ var generateButton = document.getElementById('generateButton');
+
+ if (quantity && bits) {
+ generateButton.disabled = false; // Aktiviere den Button, wenn beide Eingabefelder einen Wert enthalten
+ } else {
+ generateButton.disabled = true; // Deaktiviere den Button, wenn mindestens eines der Eingabefelder leer ist
+ }
+}
+
+// Eventlistener für die Eingabefelder, der die Überprüfungsfunktion aufruft
+document.getElementById('quantity').addEventListener('input', checkInputFields);
+document.getElementById('bits').addEventListener('input', checkInputFields);
+
+/*-----------------------------Initiale Deaktivierung von Generate und Shutdown Buttons-----------------------------*/
+document.getElementById('generateButton').disabled = true;
+document.getElementById('shutdownButton').disabled = true;
+
+/*------------------------------------------Loading Spinner-----------------------------------------------*/
+// Zeige den Lade-Spinner an und blockiere den Inhalt
+function showLoadingSpinner(loadingText) {
+ document.getElementById('overlay').classList.remove('hidden');
+ document.getElementById('loadingSpinner').classList.remove('hidden');
+ document.getElementById('loadingText').innerText = loadingText;
+}
+
+// Blende den Lade-Spinner aus und entsperre den Inhalt
+function hideLoadingSpinner() {
+ document.getElementById('overlay').classList.add('hidden');
+ document.getElementById('loadingSpinner').classList.add('hidden');
+ document.getElementById('loadingText').innerText = '';
+}
\ No newline at end of file
diff --git a/REST/style.css b/REST/style.css
new file mode 100644
index 0000000..ec82d91
--- /dev/null
+++ b/REST/style.css
@@ -0,0 +1,267 @@
+body {
+font-family: Arial, sans-serif;
+background-color: #292C35;
+color: #DCAE52;
+}
+
+table {
+font-family: monospace, Arial, sans-serif;
+max-width: 100%;
+width: 100%;
+border-collapse: collapse;
+margin-bottom: 100px;
+background-color: #292C35;
+color: #DCAE52;
+font-size: 14px;
+border: 1px solid #DCAE52;
+}
+
+th, td {
+border: 1px solid #DCAE52;
+}
+
+td {
+text-align: center;
+padding: 5px;
+}
+
+h1 {
+color: #DCAE52;
+text-align: center;
+}
+
+.disabled-input {
+
+}
+
+form {
+background-color: #292C35;
+border-radius: 5px;
+box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+padding: 20px;
+width: 50%;
+margin: 0 auto;
+}
+
+label {
+display: block;
+font-weight: bold;
+margin-bottom: 10px;
+color: #DCAE52;
+}
+
+input[type="number"] {
+width: 100%;
+padding: 10px;
+margin-bottom: 20px;
+border: 1px solid #E9E2C9;
+border-radius: 5px;
+box-sizing: border-box;
+background-color: #E9E2C9;
+}
+
+.disabled-input[type="number"]:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ border-color: #cccccc;
+ background-color: #999999;
+}
+
+input[type="number"]:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ border-color: #cccccc;
+ background-color: #999999;
+}
+
+input[type="submit"] {
+background-color: #292C35;
+border: 1px solid #E9E2C9;
+/* border: none; */
+color: #DCAE52;
+padding: 10px 20px;
+text-align: center;
+text-decoration: none;
+display: inline-block;
+font-size: 16px;
+border-radius: 5px;
+cursor: pointer;
+}
+
+input[type="submit"]:hover {
+background-color: #E9E2C9;
+}
+
+input[type="button"] {
+background-color: #292C35;
+border: 1px solid #E9E2C9;
+/* border: none; */
+color: #DCAE52;
+padding: 10px 20px;
+text-align: center;
+text-decoration: none;
+display: inline-block;
+font-size: 16px;
+border-radius: 5px;
+cursor: pointer;
+}
+
+input[type="button"]:hover {
+background-color: #E9E2C9;
+}
+
+.logo {
+position: absolute;
+top: 10px;
+left: 10px;
+width: 4em;
+height: 4em;
+}
+
+@media screen and (max-width: 600px) {
+ form {
+ width: 80%;
+ position: relative;
+ }
+
+ .logo {
+ width: 2em; /* Ändern Sie die Breite des Logos für kleine Bildschirme */
+ height: 2em; /* Ändern Sie die Höhe des Logos für kleine Bildschirme */
+ }
+
+ h1 {
+ font-size: 24px; /* Ändern Sie die Schriftgröße der Überschrift für kleine Bildschirme */
+ }
+}
+
+#status {
+ margin-top: 15px;
+}
+
+#result {
+ font-family: monospace;
+ font-size: 16px;
+}
+
+.copy-button {
+background-color: #292C35;
+border: 1px solid #E9E2C9;
+color: #DCAE52;
+padding: 5px 10px;
+text-align: center;
+text-decoration: none;
+display: inline-block;
+font-size: 14px;
+border-radius: 5px;
+cursor: pointer;
+}
+
+.copy-button:hover {
+background-color: #E9E2C9;
+}
+
+.copy-button-row {
+background-color: #292C35;
+border: 1px solid #E9E2C9;
+color: #DCAE52;
+padding: 5px 10px;
+text-align: center;
+text-decoration: none;
+display: inline-block;
+font-size: 12px;
+border-radius: 3px;
+cursor: pointer;
+}
+
+.copy-button-row:hover {
+background-color: #E9E2C9;
+}
+
+.table th:first-child,
+.table td:first-child,
+.table th:nth-child(2),
+.table td:nth-child(2) {
+width: auto;
+white-space: nowrap;
+}
+
+.table th:nth-child(3),
+.table td:nth-child(3) {
+width: 100%;
+}
+
+.table thead tr {
+font-weight: bold;
+font-size: 1.2em;
+background-color: #DCE52;
+min-height: 20px;
+}
+
+/* Loading Spinner */
+#loadingSpinner {
+ width: 50px;
+ height: 50px;
+ border: 3px solid rgba(0, 0, 0, 0.1);
+ border-left-color: #DCAE52;
+ border-radius: 50%;
+ animation: spin 1s infinite linear;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 10000;
+}
+
+#loadingText {
+ color: #DCAE52;
+ font-size: 16px;
+ text-align: center;
+ margin-top: 20px; /* Anpassung des margin-top-Werts auf 20px */
+ position: fixed;
+ top: calc(50% + 45px); /* Anpassung des top-Werts auf calc(50% + 45px) */
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 10000;
+}
+
+.loading-spinner {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 10000;
+ text-align: center;
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.hidden {
+ display: none;
+}
+
+.overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.5);
+ z-index: 9999;
+}
+
+input[type="submit"]:disabled,
+input[type="button"]:disabled {
+ background-color: #999999;
+ border-color: #cccccc;
+ cursor: not-allowed;
+ opacity: 0.6;
+ color: #666666
+}
+