The Vigenère cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.
In the Vigenère cipher each letter of a message is shifted along some number of places with different shift values. To encrypt, a table of alphabets can be used, termed a tabula recta, Vigenère square, or Vigenère table. It consists of the alphabet written out 26 times in different rows, each version of the alphabet is shifted cyclically to the left compared to the previous alphabet. At different points in the encryption process, the cipher uses a different alphabet from one of the rows. The alphabet used at each point depends on a repeating keyword.
\ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \---------------------------------------------------- A| A B C D E F G H I J K L M N O P Q R S T U V W X Y Z B| B C D E F G H I J K L M N O P Q R S T U V W X Y Z A C| C D E F G H I J K L M N O P Q R S T U V W X Y Z A B D| D E F G H I J K L M N O P Q R S T U V W X Y Z A B C E| E F G H I J K L M N O P Q R S T U...
To see how this works, lets take, the message "DONTWORRYBEHAPPY" and the keyword "CHECKIO". Write the message and the keyword below, then shift each letter in the message related by corresponded letter in the repeating keyword.
Message: DONTWORRYBEHAPPY Key: CHECKIOCHECKIOCH Encrypted: FVRVGWFTFFGRIDRF
Vigenère can also be viewed algebraically. If the letters A–Z are taken to be the numbers 0–25, and addition is
performed modulo 26, then Vigenère encryption E using the key K can be written as:
C = E(M) = (M + K) % 26
Now, consider the following scenario: you and your friend use that cipher for correspondence and you've forgot the key. But, to your luck, you have an archive with encrypted and decrypted message. With that you can find the key and decrypt the new fresh message from your friend.
Three arguments. An old decrypted message, an old encrypted message and a new encrypted message as strings (unicode for py2).
The new decrypted message as a string.
decode_vigenere('HELLO', 'OIWWC', 'ICP') == "BYE"
This is a simple cipher which had widespread usage in olden times. As we can see, the key is can be easily calculated if you know a little bit about the content of the message.
all(re.match("[A-Z]+\Z", text) for text in args)
len(key) ≤ len(old_encrypted)
2 * len(key) <= len(old_encrypted) < len(new_encrypted) or len(new_encrypted) <= len(old_encrypted)