forked from unrivaledcreations/one-time-pad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
134 lines (106 loc) · 4.29 KB
/
app.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from flask import Flask, render_template, request, send_file
import os
import re
import random
import string
import socket
app = Flask(__name__)
class OneTimePadModulo26:
def __init__(self):
self.alphabet = string.ascii_uppercase
def encrypt(self, key, plaintext):
if len(key) < len(plaintext):
return False
return ''.join([self.alphabet[(self.alphabet.index(p) + self.alphabet.index(k)) % 26]
for p, k in zip(plaintext, key)])
def decrypt(self, key, ciphertext):
if len(key) < len(ciphertext):
return False
return ''.join([self.alphabet[(self.alphabet.index(c) - self.alphabet.index(k)) % 26]
for c, k in zip(ciphertext, key)])
def tty(self, text):
return ''.join([char for char in text if char in self.alphabet])
def get_vigenere_table(self):
table = []
for i in range(26):
row = self.alphabet[i:] + self.alphabet[:i]
table.append(' '.join(row))
return '\n'.join(table)
def generate_random_letters(length=2048):
return ''.join(random.choice(string.ascii_uppercase) for _ in range(length))
@app.route('/')
def index():
return render_template('index.html')
@app.route('/encrypt', methods=['POST'])
def encrypt():
cipher = OneTimePadModulo26()
user_input = request.form['plaintext'].upper()
# Ensure the 'text' directory exists
os.makedirs('text', exist_ok=True)
with open('./text/plaintext.txt', 'w') as file:
file.write(user_input)
# Generate random letters for cipher key
random_cipher_key = generate_random_letters()
with open('./text/cipherkey.txt', 'w') as file:
file.write(random_cipher_key)
plain_text = re.sub(r'[^A-Z]', '', user_input)
cipher_key = random_cipher_key.upper()
cipher_text = cipher.encrypt(cipher_key, plain_text)
if cipher_text is False:
return "Error: The key must be at least as long as the plaintext."
with open('./text/ciphertext.txt', 'w') as file:
file.write(cipher.tty(cipher_text))
message_length = len(plain_text)
cipher_key_used = cipher_key[:message_length]
return render_template('result.html',
plain_text=cipher.tty(plain_text),
cipher_key=cipher.tty(cipher_key_used),
cipher_text=cipher.tty(cipher_text),
vigenere_table=cipher.get_vigenere_table())
@app.route('/decrypt', methods=['POST'])
def decrypt():
cipher = OneTimePadModulo26()
if 'ciphertext_file' in request.files:
ciphertext_file = request.files['ciphertext_file']
if ciphertext_file.filename != '':
cipher_text = ciphertext_file.read().decode('utf-8').upper()
else:
cipher_text = request.form['ciphertext'].upper()
else:
cipher_text = request.form['ciphertext'].upper()
if 'key_file' in request.files:
key_file = request.files['key_file']
if key_file.filename != '':
key = key_file.read().decode('utf-8').upper()
else:
key = request.form['key'].upper()
else:
key = request.form['key'].upper()
# Clean up the input
cipher_text = re.sub(r'[^A-Z]', '', cipher_text)
key = re.sub(r'[^A-Z]', '', key)
# Ensure the key is long enough
if len(key) < len(cipher_text):
return "Error: The key must be at least as long as the ciphertext."
decrypted_text = cipher.decrypt(key, cipher_text)
return render_template('decrypt_result.html',
decrypted_text=cipher.tty(decrypted_text))
@app.route('/download/<filename>')
def download_file(filename):
return send_file(f'./text/{filename}', as_attachment=True)
def find_available_port(start_port=5000, max_port=65535):
for port in range(start_port, max_port + 1):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind(('localhost', port))
return port
except socket.error:
continue
return None
if __name__ == '__main__':
port = find_available_port()
if port:
print(f"Starting server on port {port}")
app.run(debug=True, port=port)
else:
print("No available ports found.")