Begueradj   Archives  About

Vigenère cipher simplified implementation

The goal of this article is not to about debating the theory of Vigenère cipher. I rather just want to focus on its implementation after I have seen several awkward ways of proceeding to it on different online programming forums.

This question on Code Review website is an example of such implementations where code duplication is obvious but which the pre-existing answers did not address.

This is the usual Vigenère cipher square where the upper horizontal columns contains the key’s alphabet whereas the most left vertical column corresponds to the alphabet of the message to cipher (or deciphered): Vigenère cipher square

Here is a text-like pseudo algorithm of the core Vigenere cipher function which can be better understood in practice by checking the code beneath it:

Here is a Python 3 implementation sample:

import string


class FileOperations:
   def __init__(self):
       pass
   
   def get_file_content(self, input_file):
       with open(input_file,'r') as input_file:
           return input_file.read()
   
   def save_to_file(self, output_file, content):
       with open(output_file, 'w') as output_file:
           output_file.write('{0}'.format(content))


class Vigenere:
 
   def __init__(self):
       self.__SECRET_KEY = 'SOMELONGSECRETKEYGOESHERE'
       self.file_operations = FileOperations()
       self.__message = self.file_operations.get_file_content('plain.txt')
      
   def encrypt(self):
       encrypted_text = self.__vigenere('encryption')
       self.file_operations.save_to_file('encrypted.txt', encrypted_text)

   def decrypt(self):
       decrypted_text = self.__vigenere('decryption')
       self.file_operations.save_to_file('decrypted.txt', decrypted_text)

   def __vigenere(self, flag):
       transformed_text = []
       index = 0
       for letter in self.__message.upper():
           weight = string.ascii_uppercase.find(letter)
           if weight != -1:
               if flag == 'encryption':
                   weight += string.ascii_uppercase.find(self.__SECRET_KEY[index])
               elif flag =='decryption':
                   weight -= string.ascii_uppercase.find(self.__SECRET_KEY[index])
               weight %= len(string.ascii_uppercase)
               if letter.isupper():
                   transformed_text.append(string.ascii_uppercase[weight])
               elif letter.islower():
                   transformed_text.append(string.ascii_uppercase[weight]).lower()
               index += 1
               if index == len(self.__SECRET_KEY):
                   index = 0
           else:
               transformed_text.append(letter)
       return ''.join(transformed_text)
       

if __name__ == '__main__':
   vigenere = Vigenere()
   vigenere.encrypt()

Written on Nov 12, 2017.