有没有办法让这个蛮力密码破解程序更快?

时间:2021-06-10 05:05:28

标签: c++ multithreading optimization

所以我对 C++ 还是很陌生,这是我用它编写的第二个程序。第一个程序是一团糟,但它有效,我决定把这个程序全部放在一个文件中。我的问题是,它运行得非常慢。我很确定这是因为它必须迭代多少个字符,但要求是它可以用任何像这样的特殊字符破解特定长度的密码。除了它必须经历的字符数之外,我不确定是什么让它运行得如此缓慢。我想知道是否是我做的不正确的事情导致它花费了这么长时间。这就是像这样的密码破解程序可以运行的速度吗?

// Password Cracker.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <atomic>
#include <vector>
#include <cmath>
#include <sstream>

std::string convertToString(char*, int);
void passwordBruteForcer(std::string, long long, long long);

std::atomic<bool> isPasswordFound = false;
std::string foundString;

int main()
{
    // Given some count of the amount of symbols that can exist in the password
    // We will calulcate how many possible passwords there are then divide work evenly between threads
    // In this case the possible symbols are all ascii codes from 32 to 126
    int numOfSymbols = 95;

    // Declarations;
    int numberOfThreads = 8;
    std::string password;
    std::vector<std::thread> vecOfThreads;

    // Loop waits for correct user input (problem required that password length be 5, change this if you want)
    while (true)
    {
        // Prompting user input
        std::cout << "Please enter a password of length 5 \n";
        std::cout << "password: ";
        std::getline(std::cin, password);
        if (password.length() == 5)
        {
            break;
        }
        else
        {
            std::cout << "Invalid password \n";
        }
    }

    long long amountOfPossiblePasswords = pow(numOfSymbols, password.length());

    // Creates threads running brute force cracker
    for (int threadNumber = 1; threadNumber <= numberOfThreads; threadNumber++)
    {
        long long startingNumber = (amountOfPossiblePasswords * (threadNumber - 1)) / numberOfThreads;
        long long endNumber = (amountOfPossiblePasswords * threadNumber) / numberOfThreads;
        long long remainder = amountOfPossiblePasswords % numberOfThreads;

        if (threadNumber == numberOfThreads)
        {
            vecOfThreads.push_back(std::thread(passwordBruteForcer, password, startingNumber, endNumber + remainder));
        }
        else
        {
            vecOfThreads.push_back(std::thread(passwordBruteForcer, password, startingNumber, endNumber));
        }
    }

    // Wait to join thread
    for (std::thread & th : vecOfThreads)
    {
        if (th.joinable())
            th.join();
    }

    // Prints the password the algorithm found
    if (isPasswordFound)
    {
        std::cout << foundString;
    }
    return 0;
}

// Will go through all "printable" ASCII characters
void passwordBruteForcer(std::string passStr, long long startingNumber, long long endNumber)
{
    int firstChar = 32;
    int lastChar = 126;
    int length = passStr.length();
    int numOfChar = 95;
    int numOfTries = pow(numOfChar, length);

    char* guess = new char[length];

    // Converts decimal to base num of chars then puts that char into array
    // For ex. 0 will be first char, and a 1 will be the next char, the number that represents the amount of possible passwords
    // will set this to be all lastChar

    long long numToBeConvert = startingNumber;

    for (int i = (length - 1); i >= 0; i--)
    {
        guess[i] = firstChar + (numToBeConvert % numOfChar);
        numToBeConvert /= numOfChar;
    }

    // This creates a string based on initialized guess then tests it
    std::string comparisonPasswordString = convertToString(guess, length);

    if (comparisonPasswordString == passStr)
    {
        isPasswordFound = true;
        foundString = comparisonPasswordString;

        delete[] guess;
        return;
    }

    // This loop goes from startingNumber to endNumber testing all passwords
    for(long long i = startingNumber; i < endNumber; i++)
    {
        if (isPasswordFound == true)
        {
            break;
        }

        long long numForGuess = i;
        for (int j = (length - 1); j >= 0; j--)
        {
            guess[j] = firstChar + (numForGuess % numOfChar);
            numForGuess /= numOfChar;
        }
        comparisonPasswordString = convertToString(guess, length);

        if (comparisonPasswordString == passStr)
        {
            isPasswordFound = true;
            foundString = comparisonPasswordString;
            break;
        }
    }
    
    delete[] guess;
}


std::string convertToString(char* charArr, int length)
{
    std::string convString;
    for (int i = 0; i < length; i++)
    {
        convString.push_back(charArr[i]);
    }
    return convString;
}

0 个答案:

没有答案