Matt - 1 year ago 68
C Question

# Caesar cipher in C, upper and lower case

I have to produce Caesar cipher decoder -- for both lower and upper case, but I am not able to think of an easy solution to do this (or at the moment even working one).

At the moment I have this loop to decipher the code by given shift

`i`
:

``````char* s1 = "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop";
int s1s = strlen(s1);
int i = 16;
char tmp[s1s+1];
for (int j = 0; j < s1s; ++j) {
char tmp_s = (char) ((int) s1[j]-i);
if(tmp_s<65){
tmp_s+=58;
}
tmp[j]=tmp_s;
}
tmp[s1s]='\0';
``````

Output should be
`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`
, at the moment it is
`abcdefghijklmnopqrstuvwxyzABCDEFGHIJQRSTUVWXYZ[\]^_`
.

I have tried some conditions, but can't really figure out the right one.

Your tests are not complete. Consider the "ASCII space":

``````\0 ... 'A' ... 'Z' ... 'a' ... 'z' ...
``````

You have here 5 areas:

1. characters before 'A'.
2. characters between 'A' and 'Z'.
3. characters between 'Z' and 'a'.
4. characters between 'a' and 'z'.
5. characters after 'z'.

What you need is to handle characters in areas 1 and 3 once shifted (since you're only performing subtractions, area 5 will never be reached).

``````char* s1 = "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop";
int s1s = strlen(s1);
int i = 16;
char tmp[s1s+1];
for (int j = 0; j < s1s; ++j) {
char tmp_s = (char) ((int) s1[j]-i);
if(tmp_s < 'A'){ /* "area 1" */
tmp_s += 'z'-'A' + 1; /* shift between 'a' and 'z' */
}
else if(tmp_s < 'a' && s1[j] >= 'a'){ /* "area 3" */
tmp_s += 'Z'-'a' + 1; /* shift between 'A' and 'Z' */
}
tmp[j]=tmp_s;
}
tmp[s1s]='\0';
``````

The code may need further adaptations if you allow `i` to be high enough to "jump" more than one area.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download