· 9 years ago · Sep 23, 2016, 03:28 PM
1/*
2
3CS50x: Implementation of Vigenere Cipher.
4
5Usage:
6 ./vigenere <secret-key>
7
8Args:
9 secret-key: A word used to encrypt the plaintext.
10
11Author: Adrian Arumugam
12Date: 23-Sep-2016
13
14*/
15
16#include <cs50.h>
17#include <ctype.h>
18#include <string.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22int main(int argc, string argv[]){
23
24 // Fail fast if argument count is not 2.
25 // This covers the actual command and first argument.
26 if (argc != 2)
27 {
28 printf("Please provide a single argument for the key.\n");
29 return 1;
30 }
31
32 char* keyword = argv[1]; // Initialize keyword
33 int c = strlen(keyword);
34
35 // Loop through the characters to identify if they are
36 // any disallowed characters.
37 for (int i = 0; i < c; i++)
38 {
39 if isalpha(keyword[i])
40 {
41 continue;
42 }
43 else
44 {
45 printf("Please enter a word for the secret key.\n");
46 return 1;
47 }
48 }
49
50 // Lets get ready to rumble with the Vigenere cipher.
51
52 char* plaintext = GetString(); // Prompt user string to encrypt
53 int n = strlen(plaintext); // Counter for for loop
54 char ciphertext[n]; // Initialize array the length of plaintext
55 int cipherval; // Initialize cipher value
56 int plainval; // Initialize plain value
57 int subkeyval; // Initialize subtraction key
58 int keyval; // Initialize to store value for key
59 int j = 0; // Counter for key char
60 const int numalpha = 26; // Number of characters in alphabet
61 const int asciinum = 65; // Used to determing correct key value
62 const int capitalend = 90; // End ascii code of A-Z
63 const int lowercaseend = 122; // End ascii code of a-z
64
65 // Loop through the plaintext array which stores the string to encrypt.
66 //
67 // Iterating through each character of the string and performing the appropriate
68 // actions.
69
70 for (int i = 0; i <= n; i++)
71 {
72 j = j % strlen(keyword);
73 plainval = (int) plaintext[i]; // Convert the current char to an integer
74 keyval = (int) toupper(keyword[j]) - asciinum; // Uppercase and lower case treated the same. This determines value(0-25)
75 cipherval = plainval + keyval; // Default cipherval
76 subkeyval = numalpha - keyval; // Default subtraction key
77
78 // Alphabet data validaton - A-Z and a-z.
79 //
80 // If True then we potentially need to execute further
81 // cipher value modification for correct encryption.
82 if isalpha(plaintext[i])
83 {
84 // If the character is an uppercase character the following happens:
85 //
86 // 1. If cipherval is > the end of the uppercase alphabet(90)
87 // then we look at whether the keyval is equal to [Zz] if yes
88 // then cipherval plainval - subkeyval(which would be 1 in this instance)
89 // 2. Otherwise the cipherval is plainval - keyval.
90 //
91 // e.g BARFOO is encrypted as CAQGON with a key of BAZ
92 // 66,65,82,79,79 > 67,65,81,79,78
93 if isupper(plaintext[i])
94 {
95 if (cipherval > capitalend)
96 {
97 if (keyval != numalpha - 1)
98 {
99 cipherval = plainval - keyval;
100 }
101 else
102 {
103 cipherval = plainval - subkeyval;
104 }
105 }
106 }
107 // If the character is a lowercase character the following happens:
108 //
109 // 1. If cipherval is > than the end of the lowercase alphabet(122)
110 // then cipherval is equal to plainval - subkeyval.
111 // 2. Otherwise cipherval is equal to plaintext val - keyval.
112 //
113 // e.g barfoo encrypted as caqgon with a key of BAZ
114 // 98,97,114,102,111,111 -> 99,97,113,103,111,110
115 if islower(plaintext[i])
116 {
117 if (cipherval > lowercaseend)
118 {
119 cipherval = plainval - subkeyval;
120 }
121 else
122 {
123 cipherval = plainval + keyval;
124 }
125 }
126 j++;
127 }
128 // If the character is not A-Z or a-z then we don't encrypt
129 // just copy the actual plaintext integer value to cipherval.
130 else
131 {
132 cipherval = plainval;
133 }
134 // Store the cipher value in the array
135 ciphertext[i] = (char) cipherval;
136 }
137 // Once the loop exits we can print out the cipher string.
138 // This will be the encrypted string based on the secret key provided.
139 printf("%s\n", ciphertext);
140 return 0; // Return 0 to signal completion.
141}