Проблема с моим алгоритмом грубой силы на языке C ++ - PullRequest
0 голосов
/ 05 октября 2018

Я столкнулся с вопросом, где я должен создать программу, в которой есть функция, генерирующая случайный пароль с использованием таблицы ASCII (генерирование случайных чисел с использованием srand от 0 до 256 с последующим типизацией их в символы.), Еще одна функция дляотобразить сгенерированный пароль.Затем еще одна функция для взлома сгенерированного пароля методом грубой силы.Функция, которая генерирует пароль, работает нормально, но у меня есть проблема с функцией, которая взламывает пароль.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

void Generate_Pass(char pass[5])
{
    int seed = time(NULL);
    srand(seed);
    for(int i = 0; i < 5; i++){
        pass[i] = rand()%256;
    }
}

void Display_Pass(char pass[5])
{
    for(int i = 0; i < 5; i++){
        cout << pass[i] << " ";
    }
}

void Cracked(char cracked[5], char pass[5])
{
    do
    {
        for(int a = 0; a < 5; a++){
            int b = rand()%256;
            cracked[a] = char(b);
        }
    }while(cracked[0] != pass[0]);
    do
    {
        for(int a = 0; a < 5; a++){
            int b = rand()%256;
            cracked[a] = char(b);
        }
    }while(cracked[1] != pass[1]);
    do
    {
        for(int a = 0; a < 5; a++){
            int b = rand()%256;
            cracked[a] = char(b);
        }
    }while(cracked[2] != pass[2]);
    do
    {
        for(int a = 0; a < 5; a++){
            int b = rand()%256;
            cracked[a] = char(b);
        }
     }while(cracked[3] != pass[3]);
    do
    {
        for(int a = 0; a < 5; a++){
            int b = rand()%256;
            cracked[a] = char(b);
        }
    }while(cracked[4] != pass[4]);
}

void Display_Cracked(char cracked[5])
{
    for(int i = 0; i < 5; i++){
        cout <<  cracked[i] << " ";
    }
}

int main()
{
    char pass[5];
    Generate_Pass(pass);
    cout << "The Password is: ";
    Display_Pass(pass);
    cout << "\n";
    char cracked[5];
    Cracked(cracked, pass);
    cout << "The cracked password is: ";
    Display_Cracked(cracked);
}

Это код, над которым я работал, но всякий раз, когда я запускаю функцию грубой силы,не работает, как положено.

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

A Brute Force - это решение, которое:

Систематически перечисляет всех возможных кандидатов для решения и проверяет, удовлетворяет ли каждый кандидат постановке задачи

Это означает, что вам нужно сгенерировать все возможные комбинации заданной длины.(Вы никогда не можете гарантировать, что вы сделали это, используя rand.) Поскольку упоминается @ Slava , вы не должны использовать магические числа, поэтому мы назовем эту длину:

#define LENGTH 5

Оттуда вы можете просто сделать простой вложенный while -loop:

string Cracked(const char* pass) {
    string result('\0', LENGTH);

    while(!equal(cbegin(result), cend(result), pass)) {
        if(result.back() < numeric_limits<unsigned char>::max()) {
            ++result.back();
        } else {
            for(auto it = rbegin(result); it != rend(result); *it++ = '\0') {
                if(*it < numeric_limits<unsigned char>::max()) {
                    ++(*it);
                    break;
                }
            }
        }
    }
    return result;
}
0 голосов
/ 05 октября 2018

Прежде всего, в вашем методе Cracked вы зацикливаетесь на всех пяти индексах, обусловленных только одним индексом.Вы делаете это пять раз.В среднем требуется 256 попыток для сопоставления правильного символа.Это приводит к генерации и присваиванию около 5 * 5 * 256 = 6400 целых чисел, что требует больше работы, чем вам нужно.

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

void Cracked(char cracked[5], char pass[5]) {
  for (int a = 0; a < 5; a++) {
    do {
      int b = rand() % 256;
      cracked[a] = char(b);
    } while(cracked[a] != pass[a]);
  }
}

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

Вы также заметите, что использование цикла for приводит к гораздо меньшему количеству кода, который был в основном таким же.Как правило, если вы обнаружите, что копируете код, это означает, что вы должны использовать цикл, функцию или другую конструкцию, чтобы избежать лишнего кода или чтобы компилятор сгенерировал его для вас.Это значительно упрощает поддержку вашего кода.Например, если вы хотите заменить функцию rand, используемую в каждом цикле do while, вам придется заменить ее только один раз, а не пять раз.

Кроме того, в этом случае, вероятно, было бы лучшепопробуйте все возможные значения отдельно, а не случайные значения (например, с циклом for).Я дам вам понять эту часть.

...