Search code examples
python-3.xlistfunctiondictionaryvigenere

Vigenere Encryption Program


I am working on a program that encrypts a user inputed word and key using the Vingere encryption cipher. The key can be any length and contain repeated letters. Each letter of the user inputted word is encrypted using the row of the table corresponding to the letter of the keyword under it. The encryption works with the following table here: enter image description here

I have the start of the code programed but I can't figure out how to add the encryption part into my code. Here is the program so far:

    import string

phrase = input("Please enter the phrase to be encrypted: ")  #prompt user for phrase
key = input("Please enter the key: ")   #prompt user for encryption key


   
# This code returns the encrypted text generated with the help of the key
key = list(key)
if len(phrase) == len(key):
        print(key)
else:
        for i in range(len(phrase) -
                       len(key)):
            key.append(key[i % len(key)])
phrase = phrase.replace(" ", "")\
    .translate(str.maketrans('', '', phrase.punctuation))\
    .translate(str.maketrans('','',phrase.digits))\
    .upper()
print("" . join(key))

cipher_text = []
for i in range(len(phrase)):
        x = (ord(phrase[i]) +
             ord(key[i])) % 26
        x += ord('A')
        cipher_text.append(chr(x))
print("" . join(cipher_text))


print("Your word has been successfully encrypted!")
print("Original word: ", phrase)
print("Encryption: ", cipher_text)

I'm not sure what to do from this point on. I will try to figure out how to get the encryption code, but I would need help to make the program encrypt the user input and key using the Vigenere cipher. If anyone can help out I would really appreciate it. Please show the change in code for any input you give. Thanks in advance!


Solution

  • I think you are very close. In order for the cipher to work properly, you need to also capitalize your key with

    key = key.upper()
    

    Otherwise, in the calculation you make:

    x = (ord(phrase[i]) +
                 ord(key[i])) % 26
    

    you will be adding a number associated to the unicode of a lowercase character (key[i]) rather than the uppercase one.

    In other words, both the numbers for phrase[i] and key[i] should refer to uppercase characters for the calculation to work.

    After making this change, I get the following output using the phrase "hello" and the key "richard":

    Encryption:  ['Y', 'M', 'N', 'S', 'O']
    

    This is consistent with the chart (see further below).

    Also, the part where the phrase is cleaned should be:

    phrase = phrase.replace(" ", "")\
        .translate(str.maketrans('', '', string.punctuation))\
        .translate(str.maketrans('','',string.digits))\
        .upper()
    

    The full code I have looks like:

    import string
    
    phrase = input("Please enter the phrase to be encrypted: ")  #prompt user for phrase
    key = input("Please enter the key: ")   #prompt user for encryption key
    
    key = key.upper()
       
    # This code returns the encrypted text generated with the help of the key
    key = list(key)
    if len(phrase) == len(key):
            print(key)
    else:
        for i in range(len(phrase) -
                        len(key)):
            key.append(key[i % len(key)])
    phrase = phrase.replace(" ", "")\
        .translate(str.maketrans('', '', string.punctuation))\
        .translate(str.maketrans('','',string.digits))\
        .upper()
    print("" . join(key))
    
    cipher_text = []
    for i in range(len(phrase)):
            x = (ord(phrase[i]) +
                 ord(key[i])) % 26
            x += ord('A')
            
            cipher_text.append(chr(x))
    print("".join(cipher_text))
    
    
    
    
    print("Your word has been successfully encrypted!")
    print("Original word: ", phrase)
    print("Encryption: ", cipher_text)
    

    To be more explicit about the encryption working, here is an image showing how each word lines up in my example:

    enter image description here

    The green circles indicate the outcome of the encryption according to the cipher. It matches our output result of Encryption: ['Y', 'M', 'N', 'S', 'O']