Расшифровать сообщение без ключа

0

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

ex: сдвинуть слово на один
проверить, когда вы переместили, есть ли 2 общих слова?
не продолжать
да означает, что это прекращает смещение

Теперь этот вопрос, который делает программу трудной для меня, заключается в том, что у меня нет ключа для ввода, было бы здорово, если бы у меня было это.

3 вопроса, которые у меня есть сейчас, в моей функции void ничего не печатает, вторая проблема, даже если я исправлю свою проблему (я знаю это, потому что в моей функции я добавил что-то, чтобы преобразовать строку в c_string), и проблема он не сдвинется, пока не найдет слова, которые я ищу, в строке "Common []". 3-я проблема - всякий раз, когда я компилирую, я получаю сообщение об ошибке с недопустимым преобразованием из const char ** в сравнение символов между подписанными и беззнаковыми целыми выражениями

#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;

void makeshift (string encrypt, int key)
{
    for (int i = 0 ; i<encrypt.size();i++)
    {
        cout<<encrypt<<endl; // to see what is in file way to debug
        const char *encryptedc; // this is to convert string to cstring
        encryptedc = encrypt.c_str();
        encryptedc-=key;
        cout<<"decrypted message is "<<encryptedc<<endl;
    }
}


int main (int argc, char* argv[])
{
    // this will make me compare between encrypted message to check if it
    // contains this words or not!
    const char* common[]{"the","and","in","he","with","that","as","at","do"};

    string encrypted; // The encrypted message gotten from file

    ifstream message(argv[1]); // get file name typed by user
    if(message.is_open()) // check if file is open
    {
        while (!message.eof()) // check if we reached end of file
        {
            // get the whole line in file
            getline(message,encrypted);

            ///loop throgh it to store numbers in declared varibles
            for (int i = 0 ; i < encrypted.size();i++)
            {
                makeshift(encrypted,i);

                // here is where the error occurs which is "invalid conversion
                // from const char to char
                if(encrypted.find(common) != -1)
                {
                    cout<<"found common"<<endl;
                    cout<<encrypted<<endl;
                    break;
                }
            }
        }
    }
}

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

  • 2
    Привет, CaVeMaN. Я убрал часть жира из твоего поста. Надеюсь, с тобой все в порядке. Мы сделаем все возможное, чтобы помочь и не быть слишком жесткими с вами. :)
  • 0
    спасибо, все в порядке, брат
Показать ещё 3 комментария
Теги:

2 ответа

2
Лучший ответ

Ошибка компиляции

Во-первых, вы говорите, что получаете ошибку компиляции в этой строке:

if(encrypted.find(common) != -1)

Причиной этого является то, что find() ожидает, что его аргумент будет строкой, но common - это массив строк. Другими словами, find() может искать только одно слово за раз. Он не может найти целый список слов.

Чтобы исправить это, вы захотите написать цикл и проверить каждое слово на каждой итерации.


Функция сдвига

Далее - makeshift функция. Несколько предложений есть.

  1. Нет необходимости называть c_str(). Вы можете напрямую encrypted, модифицируя каждый encrypted[i] в цикле.
  2. Он должен вернуть результат. Если вы изменяете encrypted но не возвращаете его, вызывающий объект не увидит результат.
  3. Распечатки должны быть вне цикла. Предположительно, вы просто хотите увидеть результаты до и после, после того как вы расшифровали всю строку.

Вот как это выглядит с этими проблемами:

string makeshift (string encrypt, int key)
{
    cout << encrypt << endl; // to see what is in file way to debug

    for (int i = 0 ; i<encrypt.size();i++)
    {
        encrypted[i] -= key;
    }

    cout << "decrypted message is " << encryptedc << endl;
    return encrypted;
}

И тогда вы бы назвали это так:

string decrypted = makeshift(encrypted, i);

Кстати, я не уверен, что encrypted[i] -= key; строка полностью правильная. Я предполагаю, что вам нужно будет справиться с обманом. Например, если вы вычитаете 3 из буквы "A", вы, вероятно, должны обернуться вокруг "X", правильно? Если так, я оставлю это как TODO для вас.


Проверка ошибок ввода-вывода

Наконец, позвольте говорить о I/O. В частности, этот бит кода:

ifstream message(argv[1]); // get file name typed by user

if(message.is_open()) // check if file is open
{
    while (!message.eof()) // check if we reached end of file
    {
        // get the whole line in file
        getline(message,encrypted);

        ...
    }
}

Хорошей практикой в C++ является проверка результатов операций ввода-вывода (например, getline). После того, как вы прочтете строку, вам нужно проверить, что чтение действительно сработало. Вы не хотите продолжать работу, если getline() не удалось (скажем, потому что он попал в конец файла).

Удобно, если вы пишете while (getline(...)) то это будет делать целую кучу вещей сразу - он проверяет, открыт ли файл, если он в EOF, и он будет читать строки и скажите, были ли чтения успешными. Это означает, что вы можете заменить материал выше одним контуром:

ifstream message(argv[1]); // get file name typed by user

while (getline(message, encrypted))
{
    ...
}
  • 0
    Спасибо, парень, это было отличное объяснение, и я изменил свое время на while (getline (message, encrypted), это печально, потому что один из моих прошлых профессоров сказал мне использовать его таким образом, но спасибо за это!
1

Вы передаете значение зашифрованного в импровизацию, поэтому, что бы вы ни делали в импровизированной функции, не будет меняться зашифрованная основная функция, у вас есть 2 решения здесь:

вы можете либо передать указатель зашифрованного на временную функцию

  void makeshift (string* encrypt, int key){
    for (int i = 0 ; i<encrypt.size();i++)
    {   cout<<encrypt->c_str()<<endl; // to see what is in file way to debug
        const char *encryptedc; // this is to convert string to cstring
        encryptedc = encrypt->c_str();
        encryptedc-=key;
        cout<<"decrypted message is "<<encryptedc<<endl;
    }
  }  

  int main (int argc, char* argv[]){
       ...
       makeshift(&encrypted, i);
       ...
  }

Или вы можете вернуть значение encryptedc и назначить его зашифрованным в основной функции

  string makeshift (string encrypt, int key){
    for (int i = 0 ; i<encrypt.size();i++)
    {   cout<<encrypt.c_str()<<endl; // to see what is in file way to debug
        const char *encryptedc; // this is to convert string to cstring
        encryptedc = encrypt.c_str();
        encryptedc-=key;
        cout<<"decrypted message is "<<encryptedc<<endl;
        return encryptedc; //you can assign const char* to string
    }
  }  

  int main (int argc, char* argv[]){
       ...
       encrypted = makeshift(encrypted, i);
       ...
  }
  • 0
    Спасибо Ричард

Ещё вопросы

Сообщество Overcoder
Наверх
Меню