Skip to content

Commit ad79ee2

Browse files
committed
Modified the time complextiy of encryption method, added the file support for encryption and decryption
1 parent a71618f commit ad79ee2

1 file changed

Lines changed: 82 additions & 20 deletions

File tree

ciphers/caesar_cipher.py

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
2-
32
from string import ascii_letters
3+
import os
44

5+
def show_banner(text="CaesarCipher", font="block"):
6+
f = Figlet(font=font)
7+
print(f.renderText(text))
58

69
def encrypt(input_string: str, key: int, alphabet: str | None = None) -> str:
710
"""
@@ -68,25 +71,42 @@ def encrypt(input_string: str, key: int, alphabet: str | None = None) -> str:
6871
>>> encrypt('a lowercase alphabet', 5, 'abcdefghijklmnopqrstuvwxyz')
6972
'f qtbjwhfxj fqumfgjy'
7073
"""
71-
# Set default alphabet to lower and upper case english chars
74+
# Use the provided alphabet if given, otherwise default to ascii_letters (a-z + A-Z)
7275
alpha = alphabet or ascii_letters
7376

74-
# The final result string
75-
result = ""
77+
# Create a shifted version of the alphabet by the key
78+
# This rotated alphabet will be used for mapping original characters to encrypted characters
79+
shifted = alpha[key % len(alpha):] + alpha[:key % len(alpha)]
80+
81+
# Create a translation table: original alphabet -> shifted alphabet
82+
table = str.maketrans(alpha, shifted)
83+
84+
# Apply the translation table to the input string
85+
# Characters not in the alphabet remain unchanged
86+
return input_string.translate(table)
7687

77-
for character in input_string:
78-
if character not in alpha:
79-
# Append without encryption if character is not in the alphabet
80-
result += character
81-
else:
82-
# Get the index of the new key and make sure it isn't too large
83-
new_key = (alpha.index(character) + key) % len(alpha)
88+
def encrypt_file(input_path: str, output_path: str, key: int, alphabet: str | None = None):
89+
90+
"""
91+
Encrypts a text file line by line using Caesar Cipher and writes
92+
the encrypted content to the output file.
93+
"""
94+
95+
# Use the provided alphabet if given; otherwise default to ascii_letters (a-z + A-Z)
96+
alpha = alphabet or ascii_letters
8497

85-
# Append the encoded character to the alphabet
86-
result += alpha[new_key]
98+
# Open input file for reading and output file for writing
99+
with open(input_path, 'r') as fin, open(output_path, 'w') as fout:
100+
101+
# Read the input file line by line to avoid loading the entire file into memory
102+
for line in fin:
87103

88-
return result
104+
# Encrypt the current line using the encrypt function
105+
encrypted_line = encrypt(line, key, alpha)
89106

107+
# Write the encrypted line to the output file
108+
fout.write(encrypted_line)
109+
print("File has been successfully been encrypted !!")
90110

91111
def decrypt(input_string: str, key: int, alphabet: str | None = None) -> str:
92112
"""
@@ -159,6 +179,30 @@ def decrypt(input_string: str, key: int, alphabet: str | None = None) -> str:
159179

160180
return encrypt(input_string, key, alphabet)
161181

182+
def decrypt_file(input_path: str, output_path: str, key: int, alphabet: str | None = None):
183+
184+
"""
185+
Decrypts a text file line by line using Caesar Cipher and writes
186+
the decrypted content to the output file.
187+
"""
188+
189+
# Use the provided alphabet if given; otherwise default to ascii_letters (a-z + A-Z)
190+
alpha = alphabet or ascii_letters
191+
192+
# Open input file for reading and output file for writing
193+
with open(input_path, 'r') as fin, open(output_path, 'w') as fout:
194+
195+
# Read the input file line by line to avoid loading the entire file into memory
196+
for line in fin:
197+
198+
# Encrypt the current line using the encrypt function
199+
decrypted_line = decrypt(line, key, alpha)
200+
201+
# Write the encrypted line to the output file
202+
fout.write(decrypted_line)
203+
204+
print("File has been successfully been decrypted !!")
205+
162206

163207
def brute_force(input_string: str, alphabet: str | None = None) -> dict[int, str]:
164208
"""
@@ -225,8 +269,9 @@ def brute_force(input_string: str, alphabet: str | None = None) -> dict[int, str
225269

226270
if __name__ == "__main__":
227271
while True:
272+
os.system('cls' if os.name == 'nt' else 'clear')
228273
print(f"\n{'-' * 10}\n Menu\n{'-' * 10}")
229-
print(*["1.Encrypt", "2.Decrypt", "3.BruteForce", "4.Quit"], sep="\n")
274+
print(*["1.Encrypt", "2.Encrypt a File", "3.Decrypt", "4.Decrypt a File", "5.BruteForce", "6.Quit", ], sep="\n")
230275

231276
# get user input
232277
choice = input("\nWhat would you like to do?: ").strip() or "4"
@@ -237,20 +282,37 @@ def brute_force(input_string: str, alphabet: str | None = None) -> dict[int, str
237282
elif choice == "1":
238283
input_string = input("Please enter the string to be encrypted: ")
239284
key = int(input("Please enter off-set: ").strip())
240-
241-
print(encrypt(input_string, key))
285+
alphabet_input = input("Enter custom alphabet (press Enter to use default): ").strip() or None
286+
print(encrypt(input_string, key, alphabet_input))
287+
242288
elif choice == "2":
289+
input_file_path = input("Please enter path of the input file: ")
290+
output_file_path = input("Please enter path of the output file: ")
291+
key = int(input("Please enter off-set: ").strip())
292+
alphabet_input = input("Enter custom alphabet (press Enter to use default): ").strip() or None
293+
encrypt_file(input_file_path, output_file_path, key, alphabet_input)
294+
295+
elif choice == "3":
243296
input_string = input("Please enter the string to be decrypted: ")
244297
key = int(input("Please enter off-set: ").strip())
298+
alphabet_input = input("Enter custom alphabet (press Enter to use default): ").strip() or None
245299

246-
print(decrypt(input_string, key))
247-
elif choice == "3":
300+
print(decrypt(input_string, key, alphabet_input))
301+
302+
elif choice == "4":
303+
input_file_path = input("Please enter path of the input file: ")
304+
output_file_path = input("Please enter path of the output file: ")
305+
key = int(input("Please enter off-set: ").strip())
306+
alphabet_input = input("Enter custom alphabet (press Enter to use default): ").strip() or None
307+
decrypt_file(input_file_path, output_file_path, key, alphabet_input)
308+
309+
elif choice == "5":
248310
input_string = input("Please enter the string to be decrypted: ")
249311
brute_force_data = brute_force(input_string)
250312

251313
for key, value in brute_force_data.items():
252314
print(f"Key: {key} | Message: {value}")
253315

254-
elif choice == "4":
316+
elif choice == "6":
255317
print("Goodbye.")
256318
break

0 commit comments

Comments
 (0)