Guest User

Vigenére Cipher

a guest
Jan 5th, 2021
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.20 KB | None | 0 0
  1. /*
  2. Author: Jakob Forde
  3. Date: April 7th, 2020
  4. Description: Allows the user to give a text file to be encrypted using a Vigénere cipher and a
  5.              key. The encrypted file can then be translated back into regular text using that
  6.              same key.
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11.  
  12. //This function is used to generate the size of a C-string. Used in Encrypt/Decrypt for key size.
  13. int CalcSize(char checkSize[]) {
  14.     int i = 0;
  15.     int size = 0;
  16.  
  17.     while (checkSize[i] != '\0') {
  18.         i++;
  19.         size++;
  20.     }
  21.     return size;
  22. }
  23.  
  24. //Used to create Vigenere board for encryption/decryption. Creates a specially-sized board based off of the key and text file
  25. char** VigenereBoard(char newKey[], off_t fileSize) {
  26.     int i;
  27.     int j;
  28.     int inc = 0;
  29.  
  30.     //Dynamically allocating an array thats fileSize x 94
  31.     char** myArray = (char**)malloc(fileSize*sizeof(char*)+1);
  32.     for (i=0; i<fileSize; i++){
  33.         myArray[i] = malloc(94*sizeof(char));
  34.     }
  35.  
  36.     //Filling the cipher correctly. The first column contains the key stretched to be the length of the text file (newKey).
  37.     //The first row finishes out the ASCII alphabet started with the first letter of the newKey and repeats the alphabet
  38.     //just to fill 94 characters (the entire ASCII alphabet). The second row and so on do likewise.
  39.     for (i=0; i<fileSize; i++) {
  40.         inc = 0;
  41.         for (j=0; j<94; j++) {
  42.             if (newKey[i] == ' ') { //There's no need to encrypt/decrypt the space, which is all characters in not alphabet
  43.                 break;
  44.             } else {
  45.                 myArray[i][j] = newKey[i]+inc; //Starting with newKey letter and continuing out the ASCII alphabet for the ith row
  46.                 inc++;
  47.                 if ((int)newKey[i]+ inc == 127) //127 is out of the bounds of the ASCII alphabet, so it will reset back to '!'
  48.                     inc = 33-(int)newKey[i];
  49.             }
  50.         }
  51.     }
  52.  
  53.     return myArray;
  54. }
  55.  
  56. //This cracks the cipher based off of a key, textfile, and output file name
  57. void Decrypt(char key[], char phrase[], char outputName[], off_t fileSize) {
  58.     int i;
  59.     int j = 0;
  60.  
  61.     int sizeOfKey;
  62.     int keyLocation;
  63.     int cipherLetter;
  64.     char decrypt[fileSize];
  65.    
  66.     //Calculating the size of phrase and key using a function, will be helpful later.
  67.     sizeOfKey = CalcSize(key);
  68.    
  69.     //Creating a new key. The new key is just the key but made to be as long as the text file, repeating letters if necessary.
  70.     char newKey[fileSize];
  71.     for (i=0; i<fileSize; i++) {
  72.         if ((int)phrase[i] <=32) { //If the file contains any spaces, tabs, enters, etc. they are stored as a "space" in the newKey
  73.             newKey[i] = 32;
  74.         } else {
  75.             newKey[i] = key[j];
  76.             j++;
  77.             if (j==sizeOfKey) //This will reset the key in case it is shorter than the phrase
  78.                 j = 0;
  79.             }
  80.         }
  81.  
  82.     //Calls function to dynamically allocate a properly sized board. More info in VigenereBoard function.
  83.     char** myArray = VigenereBoard(newKey, fileSize);
  84.    
  85.     //Decrypting the message. Starts each row by counting the distance from the key to the cipher letter. That
  86.     //distance is the letter of the transation.
  87.     for (i=0; i<fileSize; i++) {
  88.         cipherLetter = 0;
  89.         if (newKey[i] == ' ') { //Allows decrypted message to retain spaces, enters, tabs, etc.
  90.             decrypt[i] = phrase[i];
  91.         } else {
  92.             for (j=0; j<94; j++) {
  93.             if (phrase[i] == myArray[i][j])
  94.                 cipherLetter = j;
  95.             }
  96.             decrypt[i] = (char) cipherLetter+33; //1st letter of ASCII alphabet is 33, '!'
  97.         }
  98.     }//end of for loop
  99.  
  100.    
  101.  
  102.     //Writing the encrypted file to user specifications
  103.     FILE *toWrite;
  104.     char buffer[1];
  105.     toWrite = fopen(outputName, "w");
  106.     fwrite(decrypt, sizeof(buffer), fileSize, toWrite);
  107.     fclose(toWrite);
  108.  
  109.     //Deleting the dynamically allocated array
  110.     for(int i=0; i<fileSize; i++)
  111.         free(myArray[i]);
  112.     free(myArray);
  113. }
  114.  
  115. //This generates an encryption based off of a key and the text file given by the user
  116. void Encrypt(char key[], char* phrase, char outputName[], off_t fileSize) {
  117.     int i;
  118.     int j = 0;
  119.  
  120.     int sizeOfKey;
  121.     int phraseLocation;
  122.     int keyLocation;
  123.     char cipher[fileSize];
  124.  
  125.  
  126.     //Calculating the size of phrase and key using a function, will be helpful later
  127.     sizeOfKey = CalcSize(key);
  128.    
  129.     //Creating a new key. The new key is just the key but made to be as long as the text file, repeating letters if necessary.
  130.     char newKey[fileSize];
  131.     for (i=0; i<fileSize; i++) {
  132.         if ((int)phrase[i] <=32) { //If the file contains any spaces, tabs, enters, etc. they are stored as a "space" in the newKey
  133.             newKey[i] = 32;
  134.         } else {
  135.             newKey[i] = key[j];
  136.             j++;
  137.             if (j==sizeOfKey) //This will reset the key in case it is shorter than the phrase
  138.                 j = 0;
  139.             }
  140.         }
  141.  
  142.     //Calls function to dynamically allocate a properly sized board. More info in VigenereBoard function.
  143.     char** myArray = VigenereBoard(newKey, fileSize);
  144.  
  145.  
  146.     //Using the board generated above to create a translation. For every letter of the newKey, it searches for the ASCII
  147.     //alphabet location of the phrase letter. Each row starts from the ASCII alphabet beginning with the key, but the search
  148.     //starts from the actual beginning of the ASCII alphabet. Rotating Caesar cypher.
  149.     for (i=0; i<fileSize; i++) {
  150.         if (newKey[i] == ' ') {
  151.             cipher[i] = phrase[i]; //This allows the encryption to retain spaces, tabs, enters, etc. of the original file
  152.         } else {
  153.             phraseLocation = (int) phrase[i]-33; //33 is first letter of the ASCII alphabet (!)
  154.             cipher[i] = myArray[i][phraseLocation];
  155.         }
  156.     }
  157.  
  158.     //Writing the encrypted file to user specifications
  159.     FILE *toWrite;
  160.     char buffer[1];
  161.     toWrite = fopen(outputName, "w");
  162.     fwrite(cipher, sizeof(buffer), fileSize, toWrite);
  163.     fclose(toWrite);
  164.  
  165.  
  166.     //Deleting the dynamically allocated array
  167.     for(i=0; i<fileSize; i++) {
  168.         free(myArray[i]);
  169.     }
  170.     free(myArray);
  171. }
  172.  
  173. int main() {
  174.     typedef enum {false, true}bool; //create boolean value using typdef/enum for readability
  175.  
  176.     int choice;
  177.     bool menuCycle = true;
  178.     bool programOn = true;
  179.  
  180.     //Beginning menu, asks the user to read or write an encryption
  181.     while (programOn == true) {
  182.         while (menuCycle == true) {
  183.             printf("\n----------------VIGÉNERE CIPHER----------------\n");
  184.             printf("Press 1 to decrypt a file.\n");
  185.             printf("Press 2 to encrypt a file.\n");
  186.             printf("Press 3 to exit.\n");
  187.             scanf("%d", &choice);
  188.             if (choice==1 || choice==2 || choice==3)
  189.                 menuCycle = false;
  190.             else
  191.                 printf("Try again\n");
  192.         } // end of menuCycle while loop
  193.    
  194.     menuCycle = true;
  195.  
  196.     //switch case for reading or writing
  197.     switch (choice) {
  198.         //Variables used for both cases:
  199.             //Maximum size of key or filename is 128 characters
  200.             char fileName[128];
  201.             char outputName[128];
  202.             char key[128];
  203.             char buffer[100];
  204.             off_t fileSize; //Using off_t because it can hold more space than int just in case file is VERY large
  205.             FILE* infile;
  206.  
  207.             case 1:
  208.                 printf("----------------DECRYPTING A FILE----------------\n");
  209.                
  210.                 //Asking user for the file to decrypt
  211.                 while (menuCycle == true) {
  212.                     printf("Please enter the name of the file you would like to decrypt:\n");
  213.                     scanf("%s", fileName);
  214.  
  215.                     //Creating a file pointer. If the file name can't be found, program will
  216.                     //ask user to input a valid name.
  217.                     infile = fopen(fileName, "r");
  218.                     if (infile == NULL) //file can't be found
  219.                         printf("This file does not exist. Please try again\n");
  220.                     else {
  221.                         menuCycle = false;
  222.                     }
  223.                 } // end of picking file name loop
  224.                    
  225.                 //This traverses the entirety of the file and stores its size in bytes in fileSize.
  226.                 fseek(infile, 0, SEEK_END);
  227.                 fileSize = ftell(infile);
  228.                 fseek(infile, 0, SEEK_SET);
  229.  
  230.                 //Dynamically allocating c-string to fit exact size of the file given by the user.
  231.                 char* text = (char*) malloc(fileSize*sizeof(char));
  232.  
  233.                 //Storing text in file in c string, doing it in sizeof(buffer) chunks, which is 100 bytes at a time
  234.                 //Do this for a total of fileSize times.                   
  235.                 fread(text, sizeof(buffer), fileSize, infile);
  236.                 printf("File read successfully!\n");
  237.                 fclose(infile);
  238.  
  239.                 //User input for correct key and the output file name
  240.                 printf("Enter the key (NO SPACES ALLOWED):\n");
  241.                 scanf("%s", key);
  242.                 printf("What should the decrypted file be called?\n");
  243.                 scanf("%s", outputName);
  244.  
  245.  
  246.                 //Calling decrypt function to decrypt file using the correct key and placing it in a file named by the user
  247.                 Decrypt(key, text, outputName, fileSize);
  248.                 free(text);
  249.                 printf("FILE DECRYPTED!\n");
  250.                 menuCycle = true;
  251.                 break; //end of case 1
  252.  
  253.             case 2:
  254.                 printf("----------------ENCRYPTING A FILE----------------\n");
  255.  
  256.                 //Asking user for the file to encrypt
  257.                 while (menuCycle == true) {
  258.                     printf("Please enter the name of the file you would like to encrypt:\n");
  259.                     scanf("%s", fileName);
  260.  
  261.                     //Creating a file pointer. If the file name can't be found, program will
  262.                     //ask user to input a valid name.
  263.                     infile = fopen(fileName, "r");
  264.                     if (infile == NULL) //file can't be found
  265.                         printf("This file does not exist. Please try again\n");
  266.                     else {
  267.                         menuCycle = false;
  268.                     }
  269.                 } // end of picking file name loop
  270.  
  271.                 //This traverses the entirety of the file and stores its size in bytes in fileSize.
  272.                 fseek(infile, 0, SEEK_END);
  273.                 fileSize = ftell(infile);
  274.                 fseek(infile, 0, SEEK_SET);
  275.  
  276.                 //Dynamically allocating c-string to fit exact size of the file given by the user.
  277.                 text = (char*) malloc(fileSize*sizeof(char));
  278.  
  279.                 //Store text in file in the c-string, doing it in sizeof(buffer) chunks, which is 100 bytes at a time.
  280.                 //Do this for a total of fileSize times.                   
  281.                 fread(text, sizeof(buffer), fileSize, infile);
  282.                 printf("File read successfully!\n");
  283.                 fclose(infile);
  284.  
  285.                 //Asking user for the key and the file output name
  286.                 printf("Enter your key (NO SPACES ALLOWED):\n");
  287.                 scanf("%s", key);
  288.                 printf("What should the encrypted file be called?\n");
  289.                 scanf("%s", outputName);
  290.  
  291.                 //Calling encrypt function to create the encryption out of text file, key, and placing it in a file the user named
  292.                 Encrypt(key, text, outputName, fileSize);
  293.                 free(text);
  294.                 printf("FILE ENCRYPTED!\n");
  295.                 menuCycle = true;
  296.                 break; //end of case 2
  297.  
  298.             case 3: //User exits the menu and ends the program
  299.                 programOn = false;
  300.                 break;
  301.             } // end of switch statement
  302.     } //end of entire-program loop
  303.  
  304.    return 0;
  305. } // end of main
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
Add Comment
Please, Sign In to add comment