Reputation: 13
For a project, we have to make a Caesar Cipher using classes and save the encrypted message inside of a file so a user can decipher it with the program.
I input the message and it has no problem encrypting the message according to the displacement/key I input (since I gave an option for the user to place the displacement they please).
However, the problem lies in decripting the message. It seems to only decript the penultimate or last letter of what I inputted and it doesnt even bother to show the remaining characters of the message.
I have currently no idea why its acting the way it is, I figured I would have to change the message to take char variables instead of string, but that would mean rewriting a large chunk of the code, and at the moment, I would like to avoid having to rewrite the code from scratch. If there are no other options, then I guess I will have to rewrite the code.
Here is the code, (hope that helps and sorry if my message may seem messy, this is the first time I post anything here):
#include<iostream>
#include<string>
#include<fstream>
#include<ctime>
#include<cstdlib>
/* This is a program that will grab a message from the user and encrypt it, then decrypt it
It will also generate a random 8-digit character password used to access the encrypted file
It will also have the ability to allow the user to choose how many spaces the cipher will take into account */
using namespace std;
//Implement a set displacement and get displacement
class Cipherer
{
private:
int displacement;
string message;
//string decryptMessage;
public:
void setDisplacer(int key);
int getDisplacer()const;
void msgEncripter(string, int);
string getMessage()const;
void msgDecripter(string);
string getDecription()const;
};
void Cipherer::setDisplacer(int key)
{
displacement = key;
}
int Cipherer::getDisplacer()const
{
return displacement;
}
void Cipherer::msgEncripter(string msg, int key)
{
string encriptedMsg = msg;
//.size returns the number of elements
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32) //32 is the value in ASCII of the space character
{
continue;
}
else
{
if ((msg[i] + key) > 122)
{
int temp = (msg[i] + key) - 122;
encriptedMsg[i] = 96 + temp;
}
else if (msg[i] + key > 90 && msg[i] <= 96)
{
int temp = (msg[i] + key) - 90;
encriptedMsg[i] = 64 + temp;
}
else
{
encriptedMsg[i] += key;
}
}
}
message = encriptedMsg;
}
string Cipherer::getMessage()const
{
return message;
}
void Cipherer::msgDecripter(string msg)
{
string decriptedMsg;
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32)
{
continue;
}
else
{
if ((msg[i] - displacement) < 97 && (msg[i] - displacement) > 90)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else if ((msg[i] - displacement) < 65)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else
{
decriptedMsg = msg[i] - displacement;
}
}
}
message = decriptedMsg;
}
string Cipherer::getDecription()const
{
return message;
}
static const char PASSWORD_POOL[] =
"0123456789";
int poolSize = sizeof(PASSWORD_POOL) - 1;
char getRandChar()
{
return PASSWORD_POOL[rand() % poolSize];
}
int main()
{
srand(time(0));
string pass, input, msg;
int key;
Cipherer message;
ofstream outputFile;
ifstream inputFile;
outputFile.open("SecretMSG.txt");
cout << "Write a message: \n";
getline(cin, msg);
cout << "Choose the displacement of the message (0-25): ";
cin >> key;
message.setDisplacer(key);
message.msgEncripter(msg, key);
outputFile << msg;
outputFile.close();
for (int count = 0; count < 1; count++)
{
for (int i = 0; i <= 7; i++)
{
pass += getRandChar();
}
cout << pass << endl;
}
cout << "Input password " << pass << " ";
cin >> input;
if (input == pass)
{
//Make a local variable to read file
string encryptedMessage;
inputFile.open("SecretMSG.txt");
inputFile >> encryptedMessage;
inputFile.close();
cout << message.getMessage() << endl;
cout << "If you wish to decrypt the message, type in the password once again " << pass << ": ";
cin >> input;
if (input == pass)
{
message.msgDecripter(encryptedMessage);
cout << message.getDecription() << endl;
}
else
{
exit(EXIT_FAILURE);
}
}
else
{
exit(EXIT_FAILURE);
}
system("pause");
return 0;
}
Upvotes: 2
Views: 126
Reputation: 40842
In msgDecripter
your string decriptedMsg
creates a string with the size 0
, so any decriptedMsg[i] = is
undefined behavior.
In your msgEncripter
you write string encriptedMsg = msg;
, and because you create a copy of mgs
the encriptedMsg
has the same size.
So either you do string decriptedMsg = msg
or string decriptedMsg = std::string(msg.size(), ' ');
But a more c++ like approach would be to use transform.
string encriptedMsg = msg;
std::transform(encriptedMsg.begin(), encriptedMsg.end(), encriptedMsg.begin(),
[](unsigned char c) -> unsigned char {
if( c == ' ') {
return c;
} else {
// ... your other encrypting logic ...
}
});
Or using msg
as source and an empty string as target and utilize std::back_inserter
.
Upvotes: 1