JT1 JT1 - 3 months ago 25
C Question

C Caesar Cipher ASCII Alphabet Wrap

I am quite new to C. I would like to be able to shift a letter of the alphabet 'x' number of times to create a basic cipher.

I'm having trouble with the islower() function. I'm using 'i', however, I'm unable to change it to a character.

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

string p;

int main(int argc, string argv[])
{
//if argument count does not equal 2, exit and return 1
if (argc != 2)
{
printf("Less or more than 2 arguments given, exiting...\n");
return 1;
}
else //prompt user for plaintext to encrypt
{
p = GetString();
}

//take the second part of the array (the int entered by user) and store as k (used as the encryption key)
//string k = argv[1];
int k = atoi(argv[1]);

//function:
// c = (p + k) % 26;
//iterate over the characters in the string
//p represents the position in the alphabet of a plaintext letter
//c likewise represents a position in the alphabet
char new;
for (int i = 0, n = strlen(p); i < n; i++)
if (islower((char)i))
{
//printf("%c\n", p[i] + (k % 26));
printf("This prints p:%s\n", p);
printf("This prints i:%d\n", (char)i);
printf("This prints k:%d\n", k);
printf("This prints output of lower(i):%d\n", islower(i));
new = (p[i] - 97);
new += k;
//printf("%d\n", new %26 + 97);
//printf("i = |%c| is lowercase\n", i);
printf("%c\n", new % 26 + 97);
}
else {
//printf("%c", p[i] + (k % 26));
printf("This prints p:%s\n", p);
printf("This prints i:%d\n", (char)i);
printf("This prints k:%d\n", k);
printf("This prints output of lower(i):%d\n", islower(i));
new = (p[i] - 65);
new += k;
//printf("%d\n", new % 26 + 65);
//printf("i = |%c| is uppercase\n", i);
printf("%c\n", new % 26 + 65);
}
printf("\n");
}


Outputs:

jharvard@appliance (~/Dropbox/CS50x/pset2): ./caesar2 1
zZ < here is my input
This prints p:zZ
This prints i:0
This prints k:1
This prints output of lower(i):0
G < here is fails, lower case z should move to lower case a
This prints p:zZ
This prints i:1
This prints k:1
This prints output of lower(i):0
A < here is a success! upper case Z moves to upper case A

Answer

The alphabets in English are used in C as defined in ASCII. 'Z' (ASCII 90) is followed by '{' only (ASCII 91). To go back to 'A', you should do all the shifts in the following manner:

  1. Subtract your ASCII character by 65. It'll lead to output between 0 to 25 (inclusive).
  2. Add the displacement (shift distance).
  3. Take a modulo 26, to wrap around your result.
  4. Add 65 back again.

Remember, this will work only for capital alphabets of the English language. So you may want to use toupper() from the ctype.h library.

If you want to add similar functionality for small characters, do the above procedure, replacing 65 by 97. To check if you got a small character or a capital, use isupper(). You'll have to add more and specific code for special characters.

Comments