I want to write a python function that automatically finds the key of any encrypted text and decrypt the text. I want to use the caesar cipher encryption algorithm.
This code is such that, you will enter the rot but I want the code to be able to find the rot by automatically by itself.
import string
from time import sleep
alphabet = string.ascii_lowercase # "abcdefghijklmnopqrstuvwxyz"
def decrypt(text, rot):
decrypted_text = ""
ct = open("rfc8446.txt", "r")
for cipher in text:
if cipher in alphabet: # check if character is an alphabet
position = alphabet.find(cipher) # find the index position of each text
new_position = (position - rot) % 25 # find the new index position to decrypt
new_character = alphabet[new_position] #
decrypted_text += new_character
else:
decrypted_text += cipher
print(decrypted_text)
text = "hnbcnamjh vh krtn unoc vn knqrwm"
rot = 7
decrypt(text, rot)
this will give you all possible solutions, simply by looping for all rotations.
import string
from time import sleep
def decrypt(text):
for rot in range(26):
alphabet = string.ascii_lowercase # "abcdefghijklmnopqrstuvwxyz"
decrypted_text = ""
for cipher in text:
if cipher in alphabet:
position = alphabet.find(cipher)
new_position = (position - rot) % 25
new_character = alphabet[new_position]
decrypted_text += new_character
else:
decrypted_text += cipher
print(decrypted_text)
text = "hnbcnamjh vh krtn unoc vn knqrwm"
decrypt(text)
however finding the good one is way more complicated since you need to identify which solution "looks" english, using stuff like text plausibility matrices
Related
I am currently working on a school project where I need to build a decrypter for the Vigenere Cipher. The deciphering is working out just fine, but I have a problem which is that every letter is lowercase. I know the reason for this is that my used the casefold() method for my initial string. I did it so I can compare it to the alphabet a-z. Now here is my question: How can I modify the code in so that it will return the corresponding letter in uppercase?
def decipher(key):
original = "Rpoe, Xknf cne Rosvuhcl"
string = original
Alphabet ="abcdefghijklmnopqrstuvwxyz"
dec_message = ""
key = key.lower()
string = string.casefold()
textlength = len(string)
exp_key = key
exp_key_length = len(exp_key)
while exp_key_length < textlength:
exp_key = exp_key + key
exp_key_length = len(exp_key)
key_position = 0
for letter in string:
if letter in Alphabet:
position = Alphabet.find(letter)
key_char = exp_key[key_position]
key_char_position = Alphabet.find(key_char)
key_position += 1
new_position = position - key_char_position
if new_position > 26:
new_position = new_position + 26
new_character = Alphabet[new_position]
dec_message = dec_message + new_character
else:
dec_message = dec_message + letter
print(dec_message)
print(original)
return(dec_message)
decipher("ABC")
I tried to use a for loop so I can look at each letter in the encrypted string and then .upper the letter at the corresponding position in the dec_message string, however, that didn´t work.
The encrypted text is: Rome, Wine and Portugal
I am in an into to Programming class and the assignment is in part to shift the letters of a valid password by +1 if it is a letter or number and -1 if it is a !##$ special character. I have most of it working with my below code but I always get the wrong output for the special characters. If I use to the code of anything high like 128 then I get the wrong symbol.
I am using the code from an encryption program from the other week and slowly changing things but I feel like this is too involved for something simple
If I enter the password UMA#augusta2020 I need to get the output VNB?bvhvtub3131 but I either end up with a space, b, or wrong symbol when I change the code input between 26,64,96,128, etc.
I have updated the code to fix small errors
def main():
print("This program validates and encrypts a password")
print()
main()
# The Encryption Function
def cipher_encrypt(plain_text):
encrypted = ""
for c in plain_text:
if c.isupper(): #check if it's an uppercase character
c_index = ord(c) - ord('A')
# shift the current character by key positions
c_shifted = (c_index + 1) % 26 + ord('A')
c_new = chr(c_shifted)
encrypted += c_new
elif c.islower(): #check if its a lowecase character
c_index = ord(c) - ord('a')
c_shifted = (c_index + 1) % 26 + ord('a')
c_new = chr(c_shifted)
encrypted += c_new
elif c.isdigit():
# if it's a number,shift its value
c_new = (int(c) + 1) % 10
encrypted += str(c_new)
else:
# if its neither alphabetical nor a number, -1
c_shifted = (c_index - 1) % 128 + ord('a')
c_new = chr(c_shifted)
encrypted += c_new
return encrypted
plain_text =input("Enter your Password: ")
print()
ciphertext = cipher_encrypt(plain_text)
print()
print("Your Password: ", plain_text)
print()
print("Your password is valid and encrypted it is: ", ciphertext)
print()
Here is a much cleaner approach:
def cipher_encrypt(plain_text):
alpha = 'abcdefghijklmnopqrstuvwxyz'
digits = '0123456789'
puncs = '!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~'
encrypted_text = ''
for c in plain_text:
if c.lower() in alpha:
c_index = alpha.index(c.lower())
e_index = (c_index + 1)%len(alpha)
if c == c.lower():
encrypted_text += alpha[e_index]
else:
encrypted_text += alpha[e_index].upper()
elif c in digits:
c_index = digits.index(c)
e_index = (c_index + 1)%len(digits)
encrypted_text += digits[e_index]
else:
c_index = puncs.index(c)
e_index = (c_index +len(puncs) - 1)%len(puncs)
encrypted_text += puncs[e_index]
return encrypted_text
In this approach I deal with each caharcter in plain text by:
Determining idf the char is part of alpha by making use of the c.lower() function to isolate alpha chars and then find an index modulo the len of alpha. Then I determine if I need an uppercase char or lower case in the encrypted text.
I use the same modulo approach for digits, but don't have to worry about upper and lower, finally
I find the index for the punctuations found in the plain_text
So currently I am working on a Caesar cypher app, my code looks like this (coded by RAD software https://anvil.works/)
The problem is that I don't get any output when I try to run the program and I think that it could be self.text_area_2 = cipher_encrypt(plain_text, key). I'm not sure if I'm using the correct statement to display the output correctly.
What statement should I use instead? Am I doing the right thing?
from ._anvil_designer import Form2Template
from anvil import *
class Form2(Form2Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
def button_1_click(self, **event_args):
def cipher_encrypt(plain_text, key):
plain_text = self.text_area_1.text
key = self.text_box_1.text
encrypted = ""
for c in plain_text:
if c.isupper(): #check if it's an uppercase character
c_index = ord(c) - ord('A')
# shift the current character by key positions
c_shifted = (c_index + key) % 26 + ord('A')
c_new = chr(c_shifted)
encrypted += c_new
elif c.islower(): #check if its a lowecase character
# subtract the unicode of 'a' to get index in [0-25) range
c_index = ord(c) - ord('a')
c_shifted = (c_index + key) % 26 + ord('a')
c_new = chr(c_shifted)
encrypted += c_new
elif c.isdigit():
# if it's a number,shift its actual value
c_new = (int(c) + key) % 10
encrypted += str(c_new)
else:
# if its neither alphabetical nor a number, just leave it like that
encrypted += c
return encrypted
self.text_area_2 = cipher_encrypt(plain_text, key)
For my programming class, I've been instructed to create two programs, each using the same two helper functions: alphabet_position(letter) and rotate_character(char, rot). One function uses the Caesar cipher to encrypt a message with a number of rotations, each given from the command line. The second program is meant to put more use to my Caesar program by turning it into the Vigenere Cipher. Both programs are meant to ignore (i.e., not rotate) special characters and I don't think numbers matter either. However, if the input letter is capitalized, the rotated output letter should be as well.
I've run into several issues with my code: My Caesar program only prints some capital letters. For example, with the arguments Hello, World! and 4, I receive an output of Lipps, svph! and I cannot figure out why that last capital letter isn't printing. When I attempt to pass in pYthon with 26 rotations, my program prints nothing.
My Vigenere program is also doing an odd thing with capital letters: with the passed arguments being Hello, World! and boom, I receive Iszxp, mr!.
Assignment is due in 48 hours and I'm kind of freaking out. 😬 Any and all help, criticism, etc. is welcome!
def alphabet_position(letter):
"""receives a letter and returns the 0-based numerical position of that letter within the alphabet."""
letter = letter.lower()
alphabet = "abcdefghijklmnopqrstuvwxyz"
numerical_pos = alphabet.find(letter)
return numerical_pos
def rotate_character(char, rot):
"""receives a character and an int 'rot', and rotates char by rot number of places to the right."""
alphabet = "abcdefghijklmnopqrstuvwxyz"
alpha_dict = dict(enumerate(alphabet))
new_char = ""
# ignore and return non-alphabetic characters
if char not in alphabet:
return char
# temporarily convert case to locate in alphabet
temp_char = char.lower()
if temp_char in alphabet:
# get original position of letter
orig_pos = alphabet_position(temp_char)
# take char, add rot to its index, mod 25 - 1
new_pos = (int(orig_pos) + int(rot))
if new_pos > 25:
new_pos = (new_pos % 25) - 1
elif new_pos < 0:
# avoid negative index error when rot is 26
new_char = char
# converting new_pos back to alpha
else:
new_char = alpha_dict[new_pos]
# if original char was upper/lower, return corresponding case for new_char
if char.islower():
new_char.lower()
else:
new_char.upper()
return new_char
from helpers import alphabet_position, rotate_character
# ------
# caesar cipher
# ------
def encrypt(text, rot):
new_text = ""
for char in text:
new_char = rotate_character(char, rot)
new_text += str(new_char)
return new_text
def main():
input_text = input("Enter a sentence to encrypt: ")
input_rot = int(input("Number of rotations: "))
print(encrypt(input_text, input_rot))
if __name__ == "__main__":
main()
from helpers import alphabet_position, rotate_character
# ------
# vigenere cipher
# ------
def encrypt(text, rot):
lower_alphabet = "abcdefghijklmnopqrstuvwxyz"
upper_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
keystream = 0
encrypted = ""
rot.lower()
for i in range(len(text)):
keychar = keystream % len(rot)
if text[i] in lower_alphabet:
new_char = rotate_character(text[i], alphabet_position(rot[keychar]))
new_char.lower()
encrypted += new_char
keystream += 1
elif text[i] in upper_alphabet:
new_char = rotate_character(text[i], alphabet_position(rot[keychar]))
new_char.upper()
encrypted += new_char
keystream += 1
else:
encrypted += text[i]
# stuck around here... vigenere isn't printing shifted capital letters and I
# can't figure out why.
return encrypted
def main():
input_text = input("Enter a sentence to encrypt: ")
input_rot = input("Enter your keyword: ")
print(encrypt(input_text, input_rot))
if __name__ == "__main__":
main()
Edit: helper functions edited to make code cleaner... Now it's only printing the one capital letter when I input pYthon with 4 rotations in Caesar. I'm lost.
I'm trying to do a Caesar Cipher and I've come pretty close. The problem is my output only prints out a single letter, not the whole line ciphered line. E is the most frequently used letter in English so the idea is to find the distance between E and the most frequently used letter in the input. And then shift everything over by that distance. I'm new at python, so I'm not very good yet. Thanks so much in advance! Here's the code I have so far:
maximum_character = unciphered_text[0]
maximum_count = unciphered_text.count(unciphered_text[0])
for char in unciphered_text:
if char is not " ":
if unciphered_text.count(char) > maximum_count:
maximum_character = char
print("The most frequent character used is: ", maximum_character)
ASCII_maximum = maximum_character.lower()
ASCII_number = ord(ASCII_maximum)
print(ASCII_number)
shift_distance = ord('e')-ASCII_number
print("The shift distance is: ", shift_distance)
def caesar_cipher(unciphered_text, shift_distance):
ciphered_text = ""
for char in unciphered_text:
cipher_process = ord(char)+shift_distance
post_translation = chr(cipher_process)
ciphered_text += post_translation
return ciphered_text
answer = caesar_cipher(unciphered_text, shift_distance)
print(answer)
You misindent return statement in caesar_cipher function.
Move your return statement out from loop:
def caesar_cipher(unciphered_text, shift_distance):
ciphered_text = ""
for char in unciphered_text:
cipher_process = ord(char)+shift_distance
post_translation = chr(cipher_process)
ciphered_text += post_translation
return ciphered_text