所以我目前正在使用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;
}
编辑:更新的代码。
答案 0 :(得分:1)
发布的代码的主要缺陷是递归函数返回一个字符串(猜测的密码),而没有向调用者提供明确的密码提示。
按值传递所有字符串,这也是一个潜在的效率问题,但是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 };
}
答案 1 :(得分:0)
即使修改了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
一词,因为它更容易,更快捷地调试程序,并且得到相同的结果。