I first did this:
// Convert ASCII range down to a value from 0 to 25
char uppercase[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char lowercase[27] = "abcdefghijklmnopqrstuvwxyz";
char convertedUppercase[27];
char convertedLowercase[27];
for (int i = 0; i <= 26; i++)
{
convertedUppercase[i] = uppercase[i] - 'A';
convertedLowercase[i] = lowercase[i] - 'a';
}
// For each character in the plaintext: (DOESN'T WORK)
for (int i = 0, n = strlen(p); i <= n; i++)
{
// Rotate the character if it's a letter // ci = (pi + k) % 26
if (isalpha(p[i]))
{
if (isupper(p[i]))
{
c[i] = ((p[i]) + k) % 26;
}
else if (islower(p[i]))
{
c[i] = ((p[i]) + k) % 26;
}
}
}
printf("ciphertext: %s\n", c);
but then I realized that the value of convertedUppercase
will just be like 0 = NUL instead of 0 = A. Can anyone give me a hint what to do?
edit:
From the CS50 Discord:
"The caesar cipher formula (p + k) % 26 works on the premise that p (the plain text character) has a value of 0 - 25 (representing a - z or A - Z)
So if your plain char is 'x', that would have a value of 23, and if your key was 2, then the ciphered char would be:
(23 + 2) % 26
( 25 ) % 26
= 25 'z'
I'm kinda lost on how to do it.
This would be so much easier if you would provide a MRE.
I guess what you are observing is that you see a truncated cipertext if you attempt to output it via printf()
with "%s"
.
This is however only because any "A" (that is a ciper A, i.e. after shifting by key) results in a 0 (which terminates string output, being the '\0'
terminator) and most other letters result in unprintable characters.
This is because you only shift by key and map to 0-25 what needs to be the number representation (i.e. numeric instead of textual ciper) here:
c[i] = ((p[i]) + k) % 26;
In order to turn into textual cipher instead of numeric ciper, you need to do
-'A'
+k
%26
+'A'
I.e.
c[i] = ((p[i]-'A') + k) % 26 + 'A';
E.g. "H" from "Hello World".
E.g. "W" from "Hello World".