Subs103017
Subs103017

Reputation: 13

Making a Caesar Cypher, and it does not want to decipher the message

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

Answers (1)

t.niese
t.niese

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

Related Questions