11from __future__ import annotations
2-
32from 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
69def 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
91111def 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
163207def 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
226270if __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 ("\n What 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