This is a simple cyphering program. The user executes the program with a 26-character argument. That argument specifies the key by which text will be encrypted by informing the program the order of the 26 letters of the alphabet. More specifically, the normal order of the 26 letters of the alphabet is "mapped" onto this new order in an effort to obfuscate text.
Once the program is launched the user is prompted for a block of text to encrypt. The program then prints out the new encrypted text while preserving the original case. That is, the original case takes precedent over the case of the key.
Code: Select all
//This program encrypts a block of text that is given by the user using a substitution cypher.
//Importing libraries that our project may need.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cs50.h>
#include <math.h>
#include <ctype.h>
// Lower and upper case letters are stored in predefined arrays as needed
char LETTERS[26] = {'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'};
char LOWERLETTERS[26] = {'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'};
//This function checks for duplicate letters.
bool no_repeat(string arg_letters);
int main(int argc, string argv[])
{
//This block of code checks to see if the proper number of arguments was passed into the program.
if (argc != 2)
{
printf("Usage: ./substitution key\n");
exit(1);
}
//This block of code assigns the first and only argument to a new variable.
//We assess the length of that new variable.
string argument = argv[1];
int length = strlen(argument);
//Here we ensure the length is 26
if (length != 26)
{
printf("Usage: ./substitution key\n");
exit(1);
}
//This block of code uses the ASCII table to make sure that the argument is fully alphabetical and non-numeric
for (int i = 0; i < length; i++)
{
if (!(argument[i] >= 65 && argument[i] <= 90) && !(argument[i] >= 97 && argument[i] <= 122))
{
printf("Usage: ./substitution key\n");
exit(1);
}
}
//Here we leverage our no repeat function to check for repeating characters
if(!no_repeat(argument)){
printf("Usage: ./substitution key\n");
exit(1);
}
//Now we prompt the user for a block of plain text.
string sentence = get_string("plaintext: ");
//We calculate the length of the sentence so we can loop over it later.
int senLen = strlen(sentence);
//We preemptively print the cyphertext output first since it precedes the encrypted string
printf("ciphertext: ");
//Here we establish lowercase and uppercase versions of the key so that we may preserve the case of the input block of text
//Note here how we have leveraged the use of strcpy for capitalArgument since direct assignment to a new string variable (lowerArgument) is actually a pointer
char capitalArgument[26];
strcpy(capitalArgument,argument);
string lowerArgument = argument;
//Here we convert all letters in the capital argument to actually being capitals
for (int i = 0; i < 26; i++) {
if (capitalArgument[i] >= 'a' && capitalArgument[i] <= 'z')
{
capitalArgument[i] = capitalArgument[i] - 32;
}
}
// Here we convert all letters in the lowercase argument to actually being lowercase
for (int i = 0; i < 26; i++) {
if (lowerArgument[i] >= 'A' && lowerArgument[i] <= 'Z')
{
lowerArgument[i] = lowerArgument[i] + 32;
}
}
//We iterate over the string contents
for (int i = 0; i < senLen; i++)
{
//If the letter in the plaintext block is a capital we find the array position in our capital alphabet. We then transpose that array position and find the corresponding capitalized letter of the key.
if (sentence[i] >= 65 && sentence[i] <= 90)
{
for (int j = 0; j <= 25; j++)
{
if (sentence[i] == LETTERS[j])
{
// int code = (j + key) % 26;
printf("%c", capitalArgument[j]);
}
}
}
//If the letter in the plaintext block is a lowercase we find the array position in our lowercase alphabet. We then transpose that array position and find the corresponding lowercase letter of the key.
else if (sentence[i] >= 97 && sentence[i] <= 122)
{
for (int j = 0; j <= 25; j++)
{
if (sentence[i] == LOWERLETTERS[j])
{
// int code = (j + key) % 26;
printf("%c", lowerArgument[j]);
}
}
}
//Anything that is not alphabetical in nature will simply be printed out as is.
else
{
printf("%c",sentence[i]);
}
}
printf("\n");
return 0;
}
//This is our function that tests for non-repeating characters in the key.
bool no_repeat(string arg_letters)
{
for (int i = 0, j = strlen(arg_letters); i < j; i++)
{
for (int k = i+1; k < j; k++)
{
if (arg_letters[i] == arg_letters[k])
{
return false;
}
}
}
return true;
}