所以我对 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;
}