116 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Python Caeser Cipher Helper v1.2.0
 | |
| # Usage (encrypt): python3 caeser-cipher.py encrypt secretmessage
 | |
| # Usage (decrypt): python3 caeser-cipher.py decrypt secretmessage
 | |
| 
 | |
| import re # Import Regex tools
 | |
| import string # Import string tools
 | |
| import collections # Import tools to sort letters.
 | |
| import argparse
 | |
| 
 | |
| parser = argparse.ArgumentParser(usage="(encrypt): python3 caeser-cipher.py encrypt [secretmessage] [shift]\nusage: (decrypt): python3 caeser-cipher.py decrypt [secretmessage] [shift]\nusage: If you don't know the shift of encrypted text, use 0\nusage: For example: python3 caeser-cipher.py decrypt hhhhh 0")
 | |
| parser.add_argument("action")
 | |
| parser.add_argument("ciphertext")
 | |
| parser.add_argument("shiftNum")
 | |
| args = parser.parse_args()
 | |
| 
 | |
| shiftNum = args.shiftNum
 | |
| ciphertext = re.sub (r'([^a-zA-Z]+?)', '', args.ciphertext) # Remove all non-letters.
 | |
| ciphertext = ciphertext.lower() # Make it all lowercase. https://www.geeksforgeeks.org/isupper-islower-lower-upper-python-applications/
 | |
| letters = list(string.ascii_lowercase) # Use a list of lowercase letters. https://stackoverflow.com/questions/43918437/how-to-iterate-through-the-alphabet
 | |
| 
 | |
| def encrypt(ciphertext, shiftNum, letters): # Grab parameters
 | |
| 
 | |
|     # Create local variables for this function.
 | |
| 
 | |
|     letterCount = 0
 | |
|     letterPos = 0
 | |
|     answer = ""
 | |
| 
 | |
|     for c in ciphertext: # For every letter in the ciphertext
 | |
|         while letterPos < 26: # While the letter's position in the alphabet is less than 26 (and thus valid), continue.
 | |
| 
 | |
|             if ciphertext[letterCount] == letters[letterPos]: # Match the letter in the ciphertext to a letter in the alphabet and once they match, continue.
 | |
|                 letter = int(letterPos) + int(shiftNum) # Take the position of the letter and the shift number and add them for the enciphered letter.
 | |
| 
 | |
|                 if letter > 25: # If the enciphered letter's position is not valid because it is too high, fix it by rotating around the alphabet.
 | |
|                     letter = letter - 26
 | |
|                 if letter < 0:
 | |
|                     letter = letter + 26 # If the enciphered letter's position is not valid because it is too low, fix it by rotating around the alphabet.
 | |
| 
 | |
|                 answer = answer + letters[letter] # Add letters together to get the enciphered text.
 | |
| 
 | |
|             letterPos = letterPos + 1 # Iterate through letter positions in the alphabet. (neccessary to find one that matches.)
 | |
| 
 | |
|         if letterPos > 25: # If the letter position is greater than 25, cycle back through the alphabet.
 | |
|             letterPos = letterPos - 26
 | |
| 
 | |
|         letterCount = letterCount + 1 # Keep track of how many times we're doing this.
 | |
| 
 | |
|     return print("\nYour enciphered text is: " + answer)
 | |
| 
 | |
| 
 | |
| def decrypt(ciphertext, shiftNum, letters): # Grab parameters
 | |
| 
 | |
|     # Create local variables for this function.
 | |
| 
 | |
|     letterCount = 0
 | |
|     letterPos = 0
 | |
|     answer = ""
 | |
| 
 | |
|     for c in ciphertext: # For every letter in the ciphertext
 | |
|         while letterPos < 26: # While the letter's position in the alphabet is less than 26 (and thus valid), continue.
 | |
| 
 | |
|             if ciphertext[letterCount] == letters[letterPos]: # Match the letter in the ciphertext to a letter in the alphabet and once they match, continue.
 | |
|                 letter = int(letterPos) - int(shiftNum) # Take the position of the letter and the shift number and add them for the enciphered letter.
 | |
| 
 | |
|                 if letter > 25: # If the enciphered letter's position is not valid because it is too high, fix it by rotating around the alphabet.
 | |
|                     letter = letter - 26
 | |
|                 if letter < 0:
 | |
|                     letter = letter + 26 # If the enciphered letter's position is not valid because it is too low, fix it by rotating around the alphabet.
 | |
| 
 | |
|                 answer = answer + letters[letter] # Add letters together to get the enciphered text.
 | |
| 
 | |
|             letterPos = letterPos + 1 # Iterate through letter positions in the alphabet. (neccessary to find one that matches.)
 | |
| 
 | |
|         if letterPos > 25: # If the letter position is greater than 25, cycle back through the alphabet.
 | |
|             letterPos = letterPos - 26
 | |
| 
 | |
|         letterCount = letterCount + 1 # Keep track of how many times we're doing this.
 | |
| 
 | |
|     return print("\nYour decrypted text is: " + answer)
 | |
| 
 | |
| 
 | |
| def freq(ciphertext):
 | |
|     # Create local variables for this function.
 | |
| 
 | |
|     commonletter = 0
 | |
|     letterCount = 0
 | |
|     letterPos = 0
 | |
|     answer = ""
 | |
| 
 | |
|     commonletter = collections.Counter(ciphertext).most_common()[0][0] # Find most common letter and thus the shift https://stackoverflow.com/questions/47251934/how-to-count-the-most-frequent-letter-in-a-string
 | |
| 
 | |
|     for c in ciphertext:
 | |
|         while letterPos < 26:
 | |
| 
 | |
|             if not commonletter == 0:
 | |
|                 if commonletter == letters[letterPos]: # If the most frequent letter matches the current letter, set the shift to that letter because that is the shift for the cipher. Forgot the double equals for comparison.
 | |
| 
 | |
|                     shiftNum = letterPos - 4
 | |
| 
 | |
|             if letterPos > 25: # If the letter position is greater than 25, cycle back through the alphabet.
 | |
|                 letterPos = letterPos - 26
 | |
| 
 | |
|             letterPos = letterPos + 1 # Iterate through letter positions in the alphabet. (neccessary to find one that matches.)
 | |
| 
 | |
|     decrypt(ciphertext, shiftNum, letters) # Decrypt using the frequency found in here.
 | |
| 
 | |
| 
 | |
| if args.action == "encrypt":
 | |
|     encrypt(ciphertext, shiftNum, letters) # Start the encrypt() function while passing 3 variables as parameters.
 | |
| if args.action == "decrypt":
 | |
|     if shiftNum == "0":
 | |
|         freq(ciphertext)
 | |
|     else:
 | |
|         decrypt(ciphertext, shiftNum, letters)
 |