Reputation: 87
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.
Upvotes: 0
Views: 1137
Reputation: 15976
Your tests are not complete. Consider the "ASCII space":
\0 ... 'A' ... 'Z' ... 'a' ... 'z' ...
You have here 5 areas:
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).
You should also use characters in your conditions instead of numerical values for readability. Try:
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.
Upvotes: 1