I am testing my substitution.c
program, but I get every time different results for the same code.
On the very 1.st time I got all good but :( does not encrypt non-alphabetical characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key expected "ciphertext: Yq...", not ""
. According assignment, non-alphabetical characters should stay unchanged.
So I tried another test with the same code and I got:
:) substitution.c exists
:) substitution.c compiles
:( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
expected "ciphertext: Z\...", not ""
:) encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
:) encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key
:) encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key
:( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZTEOGXHCIPJSQD as key
expected "ciphertext: Cb...", not ""
:) encrypts "This is CS50" as "Cbah ah KH50" using yukfrnlbavmwzteogxhcipjsqd as key
:) encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZteogxhcipjsqd as key
:) encrypts all alphabetic characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key
:( does not encrypt non-alphabetical characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key
expected "ciphertext: Yq...", not ""
:) handles lack of key
:) handles too many arguments
:) handles invalid key length
:) handles invalid characters in key
:) handles duplicate characters in uppercase key
:) handles duplicate characters in lowercase key
:) handles multiple duplicate characters in key
Once I've got all checks good, another time completely different. And apart this problem, the A
character should be encrypted as Z
with ZYXWVUTSRQPONMLKJIHGFEDCBA
key. So why is the result negative? Any idea what could get wrong? Thanks!
My code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// prototypes
int verifyKey(int argc, string key);
int encrypt(string key, string plaintext);
string toupperText(string text);
int main(int argc, string argv[])
{
string key = argv[1];
// verify used key
int keyOK = verifyKey(argc, key);
if (keyOK == 1)
{
return 1;
}
// prompt user for text to be encrypted
string plaintext = get_string("plaintext: ");
// print
printf("ciphertext: ");
// encrypt text
int ciphertext = encrypt(key, plaintext);
return 0;
}
int verifyKey(int argc, string key)
{
const string WARNING_USAGE = "Usage: ./substitution key";
// prompt user for exactly one cmd argument
if (argc != 2)
{
printf("%s\n", WARNING_USAGE);
return 1;
}
// cmd argument must be 26 characters long
if (strlen(key) != 26)
{
printf("Key must contain 26 characters.\n");
return 1;
}
// handle invalid characters in key
for (int i = 0; i < strlen(key); i++)
{
if (!isalpha(key[i]))
{
printf("%s\n", "Key must contain only alphabetical characters.\n");
return 1;
}
}
// handle duplicate characters in key
char testKey[strlen(key)];
for (int i = 0; i < strlen(key); i++)
{
//
for (int j = 0; j < strlen(testKey); j++)
{
if (key[i] == testKey[j])
{
printf("%s\n", WARNING_USAGE);
return 1;
}
}
testKey[i] = key[i];
}
return 0;
}
int encrypt(string key, string plaintext)
{
// key to upper case for easier computing
key = toupperText(key);
// ASCII values from key
int keyIndexes[strlen(key)];
for (int i = 0; i < strlen(key); i++)
{
// get ASCII value for i-th key character
int ascii = (int) key[i];
keyIndexes[i] = ascii;
}
// array of ASCII values of encrypted text
int encryptedtext[strlen(plaintext)];
// loop through plaintext
for (int i = 0; i < strlen(plaintext); i++)
{
char c = plaintext[i];
// if character is alphabetical -> encrypt
if (isalpha(c))
{
// get ASCII value of character
int index = (int) c;
// get position in alphabet
index -= 65;
int moveToUpper = 0;
if (islower(c))
{
// get position in alphabet for lowercase characters
moveToUpper = 32;
}
encryptedtext[i] = keyIndexes[index - moveToUpper] + moveToUpper;
}
else
{
encryptedtext[i] = c;
}
printf("%c", (char) encryptedtext[i]);
}
printf("\n");
return 0;
}
string toupperText(string text)
{
for (int i = 0; i < strlen(text); i++)
{
text[i] = toupper(text[i]);
}
return text;
}