所以我目前正在做一个C++的暴力破解攻击器项目。我已经设法让它工作了,但我面临的一个问题是,如果程序实际上设法得到了正确的猜测,函数仍然会继续运行。我认为问题在于程序没有返回一个猜测。看看我的代码:(顺便说一句,很抱歉,我对C++不是很有经验--我曾经用Python/JS编写代码。)
#include <iostream>
#include <cstdlib>
#include <string>
std::string chars = "abcdefghijklmnopqrstuvwxyz";
std::string iterateStr(std::string s, std::string guess, int pos);
std::string crack(std::string s);
std::string iterateChar(std::string s, std::string guess, int pos);
int main() {
crack("bb");
return EXIT_SUCCESS;
}
// this function iterates through the letters of the alphabet
std::string iterateChar(std::string s, std::string guess, int pos) {
for(int i = 0; i < chars.length(); i++) {
// sets the char to a certain letter from the chars variable
guess[pos] = chars[i];
// if the position reaches the end of the string
if(pos == s.length()) {
if(guess.compare(s) == 0) {
break;
}
} else {
// else, recursively call the function
std::cout << guess << " : " << s << std::endl;
iterateChar(s, guess, pos+1);
}
}
return guess;
}
// this function iterates through the characters in the string
std::string iterateStr(std::string s, std::string guess, int pos) {
for(int i = 0; i < s.length(); i++) {
guess = iterateChar(s, guess, i);
if(s.compare(guess) == 0) {
return guess;
}
}
return guess;
}
std::string crack(std::string s) {
int len = s.length();
std::string newS(len, 'a');
std::string newGuess;
newGuess = iterateStr(s, newS, 0);
return newGuess;
}编辑:更新代码。
发布于 2018-10-29 06:28:11
发布的代码中的主要缺陷是,递归函数返回一个字符串(猜测的密码),但没有明确指示调用者已找到密码。
通过值传递所有字符串也是一个潜在的效率问题,但OP应该担心这样的代码片段:
guess[pos] = chars[i]; // 'chars' contains the alphabet
if(pos == s.length()) {
if(guess.compare(s) == 0) {
break;
}
} 其中guess和s是长度相同的字符串。如果长度为2(OP最后一个示例),则guess[2]在界限之外,但是对guess.compare(s)的连续调用将只比较“内部”的两个字符。
iterateStr中的循环也没有做任何有用的事情,并且没有使用pos参数。
与其修复这种尝试,不如从头开始重写它。
#include <iostream>
#include <string>
#include <utility>
// Sets up the variable and start the brute force search
template <class Predicate>
auto crack(std::string const &src, size_t length, Predicate is_correct)
-> std::pair<bool, std::string>;
// Implements the brute force search in a single recursive function. It uses a
// lambda to check the password, instead of passing it directly
template <class Predicate>
bool recursive_search(std::string const &src, std::string &guess, size_t pos,
Predicate is_correct);
// Helper function, for testing purpouse
void test_cracker(std::string const &alphabet, std::string const &password);
int main()
{
test_cracker("abcdefghijklmnopqrstuvwxyz", "dance");
test_cracker("abcdefghijklmnopqrstuvwxyz ", "go on");
test_cracker("0123456789", "42");
test_cracker("0123456789", "one"); // <- 'Password not found.'
}
void test_cracker(std::string const &alphabet, std::string const &password)
{
auto [found, pwd] = crack(alphabet, password.length(),
[&password] (std::string const &guess) { return guess == password; });
std::cout << (found ? pwd : "Password not found.") << '\n';
}
// Brute force recursive search
template <class Predicate>
bool recursive_search(std::string const &src, std::string &guess, size_t pos,
Predicate is_correct)
{
if ( pos + 1 == guess.size() )
{
for (auto const ch : src)
{
guess[pos] = ch;
if ( is_correct(guess) )
return true;
}
}
else
{
for (auto const ch : src)
{
guess[pos] = ch;
if ( recursive_search(src, guess, pos + 1, is_correct) )
return true;
}
}
return false;
}
template <class Predicate>
auto crack(std::string const &src, size_t length, Predicate is_correct)
-> std::pair<bool, std::string>
{
if ( src.empty() )
return { length == 0 && is_correct(src), src };
std::string guess(length, src[0]);
return { recursive_search(src, guess, 0, is_correct), guess };
}发布于 2018-10-28 13:00:34
我已经尝试过您的代码,即使使用修改后的iterateStr()函数也是如此。我使用了abduct这个词,因为它搜索起来更快。在单步执行调试器时,我注意到当找到匹配项时,iterateChar()函数没有返回。另外,我注意到传入的string s的长度是6,但是在每次迭代中更新的猜测字符串的长度是7。您可能希望单步执行您的代码,并检查这一点。
例如,在特定迭代中,s字符串包含:abduct,但guess字符串包含aaaabjz,那么在下一次迭代中,guess字符串包含aaaabkz。这可能是您关心的问题,为什么循环或函数即使在您认为找到匹配的情况下仍会继续。
这里的长度差异可能是你的罪魁祸首。
此外,在单步执行修改后的代码时:
for ( size_t i = 0; i < s.length(); i++ ) {
guess = iterCh( s, guess, i );
std::cout << "in the iterStr loop\n";
if ( guess.compare( s ) == 0 ) {
return guess;
}
}
return guess;在您的iterateStr()函数中,递归总是调用guess = iterCh( s, guess, i );,并且代码从不打印in the iterStr loop\n";。您的iterateChar函数将遍历整个字符串或字符序列,但始终未找到匹配项并返回匹配项。我甚至尝试了单词abs,因为它更容易、更快地通过调试器,并且我得到了同样的结果。
https://stackoverflow.com/questions/53027868
复制相似问题