Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Caesar and Vigenère Encryption *You may not use the Python ord() or chr() functi

ID: 3752037 • Letter: C

Question

Caesar and Vigenère Encryption

*You may not use the Python ord() or chr() function.

For this assignment, you will always leave all characters that are not letters unchanged.

Plaintext message letters may be either upper or lower case, but you should output only upper case ciphertext.

Remember that the string function upper() gives back a version of its string that has all alphabet characters converted to upper case.

I.e.,

will print out CAESAR

Note that you are writing two functions for each cryptosystem, an encrypt and a decrypt, so one partial test of the correctness of your work is whether first encrypting and then decrypting returns the original string (except that you may have converted some lower case letters to upper case).

Overview of the assignment

You will write a total of four functions, each of which will take two inputs and return a string:

c_encrypt()

c_decrypt()

vig_encrypt()

vig_decrypt()

The first argument will be a string containing the plaintext (or clear text) message to be encrypted for the two encrypt functions, and a string containing a ciphertext to be decrypted. The second argument will be the key.

For this assignment, you will always leave all characters in plaintext or ciphertext that are not letters (i.e., spaces and punctuation marks) unchanged.

Plaintext message letters may be either upper or lower case, but you should output only upper case ciphertext.

Remember the string function upper() you used in lab.

Note that you are writing two functions for each cryptosystem, an encrypt and a decrypt, so one partial test of the correctness of your work is whether first encrypting and then decrypting returns the original string (except that you may have converted some lower case letters to upper case).

Caesar Cipher

Caesar part of the homework: Write c_encrypt() and c_decrypt(), both of which take two arguments, the first one a string and the second one an integer key.

Both should return a string.

This will be much easier if both functions use the shift() function you wrote for the lab.

Vigenère Cipher

The Vigenère Cipher was more or less completely unbreakable from its introduction sometime in the 1500s until well into the 1800s.

The key in Vigenère is a key word that is used over and over again to give a different key to the Caesar cipher for each letter of the encryption (and decryption), with 'A', in good Python form, representing a rotation of 0. (We Pythonistas start at 0, not 1!)

So if the key is ABACUS, then we encrypt:

the first letter of our message with a Caesar cipher with a key/rotation of 0, because A is the first letter of the alphabet,

the second letter with a key/rotation of 1 (for the 'B'),

the third letter with a rotation of 0 (for the second 'A' of ABACUS),

the fourth letter with a key/rotation of 2 for the 'C',

the fifth letter with a key/rotation of 20 for the 'U',

the sixth letter with a key/rotation of 18 for the 'S',

and wrap back to the start of our keyword ABACUS and encrypt the seventh letter with a key/rotation of 0 for the first 'A' in ABACUS

Back in the 1800s people wanting to use this system would make use of a Vigenère square, also known as the tabula recta, shown in the middle of the Wikipedia entry for the Vigenère cipher, but we can use Python.

Vigenère part of the homework: Write vig_encrypt() and vig_decrypt() functions. Each takes two strings as inputs, with the first being the plaintext/ciphertext, and the second being the key. Both should be calling functions you wrote earlier to help make the work easier. One check on your work: vig_encrypt("ATTACKATDAWN", "LEMON") should return the string LXFOPVEFRNHR

shift function:

def cencrypt(WORD, shift):
alpha= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
letters= alpha.upper();
encryption= ''
for ch in WORD:
if ch in alpha:
num= letters.find(ch)
num= shift+ num
if num < 0:
num= num + len(letters)
elif num> 26:
num= num - len(letters)
encryption= encryption + ch
else:
encryption= encryption + letters[num]
return encryption

Explanation / Answer

Here is the working code for the given requirements.

Please comment below for any queries and any modifications needed with the code. Thank you

def alpha_pos(leter):
num_pos = alphabet.find(leter)
return num_pos

def rotate_char(ch, rott):
alphaDict = dict(enumerate(alphabet))
new_ch = ""
if ch not in alphabet:
return ch
tempChar = ch.lower()
if tempChar in alphabet:
original_pos = alpha_pos(tempChar)
newPosition = (int(original_pos) + int(rott))
if newPosition > 25:
newPosition = (newPosition % 25) - 1
elif newPosition < 0:
new_ch = ch
else:
new_ch = alphaDict[newPosition]
if ch.islower():
new_ch.lower()
else:
new_ch.upper()
return new_ch
from helpers import alpha_pos, rotate_char


# caesar cipher

def encrypt(txt, rott):
new_txt = ""
for ch in txt:
new_ch = rotate_char(ch, rott)
new_txt += str(new_ch)

return new_txt

def main():
in_txt = input("Enter a sentence to encrypt: ")
input_rot = int(input("Number of rotations: "))

print(encrypt(in_txt, input_rot))

if __name__ == "__main__":
main()
from helpers import alpha_pos, rotate_char

def encrypt(txt, rott):
lower_alpha = "abcdefghijklmnopqrstuvwxyz"
upper_alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key_stream = 0
encrypt = ""
rott.lower()
for i in range(len(txt)):
keychar = key_stream % len(rott)
if txt[i] in lower_alpha:
new_ch = rotate_char(txt[i], alpha_pos(rott[keychar]))
new_ch.lower()
encrypt += new_ch
key_stream += 1
elif txt[i] in upper_alpha:
new_ch = rotate_char(txt[i], alpha_pos(rott[keychar]))
new_ch.upper()
encrypt += new_ch
key_stream += 1   
else:
encrypt += txt[i]
return encrypt

def main():
in_txt = input("Enter a sentence to encrypt: ")
input_rot = input("Enter your keyword: ")

print(encrypt(in_txt, input_rot))

if __name__ == "__main__":
main()