首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++暴力攻击函数不返回结果

问C++暴力攻击函数不返回结果
EN

Stack Overflow用户
提问于 2018-10-28 10:19:37
回答 2查看 426关注 0票数 0

所以我目前正在做一个C++的暴力破解攻击器项目。我已经设法让它工作了,但我面临的一个问题是,如果程序实际上设法得到了正确的猜测,函数仍然会继续运行。我认为问题在于程序没有返回一个猜测。看看我的代码:(顺便说一句,很抱歉,我对C++不是很有经验--我曾经用Python/JS编写代码。)

代码语言:javascript
复制
#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;
}

编辑:更新代码。

EN

回答 2

Stack Overflow用户

发布于 2018-10-29 06:28:11

发布的代码中的主要缺陷是,递归函数返回一个字符串(猜测的密码),但没有明确指示调用者已找到密码。

通过值传递所有字符串也是一个潜在的效率问题,但OP应该担心这样的代码片段:

代码语言:javascript
复制
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参数。

与其修复这种尝试,不如从头开始重写它。

代码语言:javascript
复制
#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
EN

Stack Overflow用户

发布于 2018-10-28 13:00:34

我已经尝试过您的代码,即使使用修改后的iterateStr()函数也是如此。我使用了abduct这个词,因为它搜索起来更快。在单步执行调试器时,我注意到当找到匹配项时,iterateChar()函数没有返回。另外,我注意到传入的string s的长度是6,但是在每次迭代中更新的猜测字符串的长度是7。您可能希望单步执行您的代码,并检查这一点。

例如,在特定迭代中,s字符串包含:abduct,但guess字符串包含aaaabjz,那么在下一次迭代中,guess字符串包含aaaabkz。这可能是您关心的问题,为什么循环或函数即使在您认为找到匹配的情况下仍会继续。

这里的长度差异可能是你的罪魁祸首。

此外,在单步执行修改后的代码时:

代码语言:javascript
复制
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,因为它更容易、更快地通过调试器,并且我得到了同样的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53027868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档