Делая Цезаря Сайфера, и он не хочет расшифровывать сообщение - PullRequest
2 голосов
/ 19 октября 2019

Для проекта мы должны создать Цезарь-Шифр, используя классы, и сохранить зашифрованное сообщение внутри файла, чтобы пользователь мог расшифровать его с помощью программы.

Я ввожу сообщение, и у него нет проблем с шифрованием сообщения в соответствии с введенным мною смещением / ключом (поскольку я дал пользователю возможность разместить смещение по своему усмотрению).

ОднакоПроблема заключается в расшифровке сообщения. Кажется, он только расшифровывает предпоследнюю или последнюю букву того, что я ввел, и даже не удосуживается показать оставшиеся символы сообщения.

В настоящее время я понятия не имею, почему он действует так, как я думал, япришлось бы изменить сообщение на переменные char вместо строки, но это означало бы переписывание большого фрагмента кода, и в данный момент я бы хотел избежать необходимости переписывать код с нуля. Если других вариантов нет, то, наверное, мне придется переписать код.

Вот код (надеюсь, это поможет, извините, если моё сообщение может показаться грязным, я впервые публикую что-либоздесь):

#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;
}

1 Ответ

1 голос
/ 19 октября 2019

В msgDecripter ваш string decriptedMsg создает строку размером 0, поэтому любое decriptedMsg[i] = is неопределенное поведение.

В вашем msgEncripter вы пишете string encriptedMsg = msg;, и потому что вы создаетекопия mgs * encriptedMsg имеет тот же размер.

Так что вы либо делаете string decriptedMsg = msg, либо string decriptedMsg = std::string(msg.size(), ' ');

Но более подход, подобный c ++, будет использовать 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 ... 
      }
    });

Или используя msg в качестве источника и пустую строку в качестве цели и используйте std::back_inserter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...