patterncppMinor
Simple Caesar Cipher C++
Viewed 0 times
caesarsimplecipher
Problem
I was surprised to learn that there are not many C++ Caesar ciphers on Code Review (3 others as of this question). And none that work in this fashion.
Here's the code:
This is a very simple Caesar cipher. It currently ignores anything uppercase or non-alphabetic.
Here's an example output:
How can this code be improved?
Here's the code:
// Caesar cipher
#include
const char chars[] = {"abcdefghijklmnopqrstuvwxyz"};
// Find position in array
int findPosition(char x){
int i;
for(i = 0; i <= 25; i++){
if(x == chars[i]){
break;
}
}
return i;
}
// Change char to next in array, loop back if at end
char nextChar(char x){
if(findPosition(x) == 25){
return chars[0];
}
return chars[findPosition(x) + 1];
}
// Rotate char desired amount
char rotChar(char x, int rotNum){
for(int i = 1; i <= rotNum; i++){
x = nextChar(x);
}
return x;
}
int main(){
std::string str;
std::getline(std::cin, str);
std::cout << '\n';
for(int i = 0; i <= 25; i++){
std::cout << "ROT" << i << " - ";
for(int k = 0; str[k] != '\0'; k++){
std::cout << rotChar(str[k], i);
}
std::cout << '\n';
}
return 0;
}This is a very simple Caesar cipher. It currently ignores anything uppercase or non-alphabetic.
Here's an example output:
ROT0 - helloworld
ROT1 - ifmmpxpsme
ROT2 - jgnnqyqtnf
ROT3 - khoorzruog
ROT4 - lippsasvph
ROT5 - mjqqtbtwqi
ROT6 - nkrrucuxrj
ROT7 - olssvdvysk
ROT8 - pmttwewztl
ROT9 - qnuuxfxaum
ROT10 - rovvygybvn
ROT11 - spwwzhzcwo
ROT12 - tqxxaiadxp
ROT13 - uryybjbeyq
ROT14 - vszzckcfzr
ROT15 - wtaadldgas
ROT16 - xubbemehbt
ROT17 - yvccfnficu
ROT18 - zwddgogjdv
ROT19 - axeehphkew
ROT20 - byffiqilfx
ROT21 - czggjrjmgy
ROT22 - dahhksknhz
ROT23 - ebiiltloia
ROT24 - fcjjmumpjb
ROT25 - gdkknvnqkcHow can this code be improved?
Solution
Function by function review
findPosition()
This function is inefficient because it searches an alphabetized string trying to find the index of a lowercase letter. It would be faster to not even use the string and just compute the position directly like this:
The other problem is what to return if the input character is not found. Currently you return 26 and this causes the caller to print a null character (because
nextChar()
This function works fine, but it gets called
rotChar()
Instead of calling
Notice that this also returns the character unmodified if it wasn't a lowercase character. At this point, you might want to just eliminate
Then you could easily extend this to handle uppercase letters as well:
findPosition()
This function is inefficient because it searches an alphabetized string trying to find the index of a lowercase letter. It would be faster to not even use the string and just compute the position directly like this:
if (x >= 'a' && x <= 'z')
return x - 'a';The other problem is what to return if the input character is not found. Currently you return 26 and this causes the caller to print a null character (because
chars[26] is the end of the string). I think it would be preferable to return -1 and have the caller detect and deal with that. So in total:int findPosition(char x)
{
if (x >= 'a' && x <= 'z')
return x - 'a';
return -1;
}nextChar()
This function works fine, but it gets called
n times, where n is the number of times you are rotating. You should be able to delete this function if you modified rotChar() appropriately.rotChar()
Instead of calling
nextChar() rotNum times, you should be able to use the modulo operator to compute the next character in one step:// Rotate char desired amount
char rotChar(char x, int rotNum)
{
int pos = findPosition(x);
if (pos == -1)
return x;
return 'a' + ((pos + rotNum) % 26);
}Notice that this also returns the character unmodified if it wasn't a lowercase character. At this point, you might want to just eliminate
findPosition() and just do everything in rotChar() like this:// Rotate char desired amount
char rotChar(char x, int rotNum)
{
if (x >= 'a' && x <= 'z')
return 'a' + (((x - 'a') + rotNum) % 26);
return x;
}Then you could easily extend this to handle uppercase letters as well:
// Rotate char desired amount
char rotChar(char x, int rotNum)
{
if (x >= 'a' && x = 'A' && x <= 'Z')
return 'A' + (((x - 'A') + rotNum) % 26);
return x;
}Code Snippets
if (x >= 'a' && x <= 'z')
return x - 'a';int findPosition(char x)
{
if (x >= 'a' && x <= 'z')
return x - 'a';
return -1;
}// Rotate char desired amount
char rotChar(char x, int rotNum)
{
int pos = findPosition(x);
if (pos == -1)
return x;
return 'a' + ((pos + rotNum) % 26);
}// Rotate char desired amount
char rotChar(char x, int rotNum)
{
if (x >= 'a' && x <= 'z')
return 'a' + (((x - 'a') + rotNum) % 26);
return x;
}// Rotate char desired amount
char rotChar(char x, int rotNum)
{
if (x >= 'a' && x <= 'z')
return 'a' + (((x - 'a') + rotNum) % 26);
if (x >= 'A' && x <= 'Z')
return 'A' + (((x - 'A') + rotNum) % 26);
return x;
}Context
StackExchange Code Review Q#151276, answer score: 5
Revisions (0)
No revisions yet.