在PHP中猜测密码的递归函数?

时间:2017-06-13 17:15:30

标签: php recursion enumeration

我需要编写一个可以猜出4个字符长密码的递归函数。 我用这个来生成一个随机的“密码”:

/*start random password generating code*/
$random_password = "";
$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for($i = 0; $i < 4; $i++){
  $random_int = mt_rand();
  $random_password .= $charset[$random_int % strlen($charset)];
}
echo "The password to guess is: " . $random_password . "\n";
/*end random password generating code*/

我可以很容易地做同样的事情并通过while循环检查它是否与密码匹配,但是这个练习是用递归函数来完成的。

我该怎么做?我之前的练习只是为了计算斐波纳契数,但这有点过去了。

我应该这样做:

$counter = array(1, 0, 0, 0);
function enumurate(){
  global $counter;
  if($counter[0] != 0){
    echo $counter[0];
    if($counter[1] != 0){
      echo $counter[1];
      if($counter[2] != 0){
        echo $counter[2];
        if($counter[3] != 0){
          echo $counter[3];
        }else{
          echo 'error! $counter[3] is: ' . $counter[3];
        }
      }else{
        echo 'error! $counter[2] is: ' . $counter[2];
      }
    }else{
      echo 'error! $counter[1] is: ' . $counter[1];
    }
  }else{
    echo 'error! $counter[0] is: ' . $counter[0];
  }

}
enumurate();

我相信我正在寻找的东西是位移之间的东西(在我迭代了62次[26 + 26 + 10 =小写+大写+数字]之后)然后再次递归调用该函数但我不知所措

或者我是否想过这个?

PS:我确实在谷歌上寻找它但由于某种原因我找不到任何关于字符串枚举的递归函数匹配的具体信息以及在这里检查。我的1337搜索技能可能让我失望了。

1 个答案:

答案 0 :(得分:0)

猜测你刚刚生成的密码似乎有点无用......为什么你不会只是猜测&#34;那个密码?此外,只有生成所有可能的4个字母的单词,直到它等于您从一开始就知道的密码,就没有乐趣。谈论低效的代码......

为了减少这一点,我假设需要猜测密码的函数不会将密码作为参数获取(因为它可以将其作为唯一正确的猜测返回),而是会得到一个可以调用的回调函数来验证以下哪个是真的:

  • 猜测完全正确:回调将返回值2
  • 猜测与密码的第一个字符匹配,但完全匹配需要更多字符:在这种情况下回调将返回1
  • 所有其他情况:回调将返回0

那个回调函数看起来像这样:

function ($guess) use ($random_password) {
    if ($guess === $random_password) return 2; // it is correct!
    if (substr($random_password, 0, strlen($guess)) === $guess) return 1; // partial match;
    return 0; // the password does not start with the guessed characters
}

通过这种设置,挑战更有趣,因为解决方案不会被允许查看它需要猜测的密码。

然后是递归解决方案(跟随你的函数产生随机密码):

function getRandomPassword() { // Your function
    $random_password = "";
    $charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    for($i = 0; $i < 4; $i++){
        $random_int = mt_rand();
        $random_password .= $charset[$random_int % strlen($charset)];
    }
    return $random_password;
}

function findPassword($evaluateGuess) {
    $charset = str_split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

    function guessTheRest(&$evaluateGuess, &$charset, $password) {
        $match = $evaluateGuess($password); // call the callback function
        if ($match === 0) return; // mismatch
        if ($match === 2) return $password; // all characters correct
        foreach ($charset as $char) { // taking each character as a "guess"
            $guess = guessTheRest($evaluateGuess, $charset, $password . $char);
            if ($guess) return $guess;
        }
    }

    return guessTheRest($evaluateGuess, $charset, "");
}

$random_password = getRandomPassword();
echo "The password to guess is: $random_password\n";

$guess = findPassword(function ($guess) use ($random_password) {
    if ($guess === $random_password) return 2; // it is correct!
    if (substr($random_password, 0, strlen($guess)) === $guess) return 1; // partial match;
    return 0; // the password does not start with the guessed characters
});

echo "guessed $guess\n";

repl.it上看到它。