PHP暴力破解密码生成器

3

我希望能够输入一个数字并获取一个由字符串或独特字符生成的密码。所以如果我的字符串中有两个字符:$string = "AB",那么期望的结果如下:

-in-|-out-
 0  |  A
 1  |  B
 2  | AA
 3  | AB
 4  | BA
 5  | BB
 6  | AAA
 7  | AAB
 8  | ABA
 9  | ABB
 10 | BBB

以下是我的当前代码:

for($i = 1; $i < 100; $i++)
{
    echo createString ($i, "AB")."<br/>";
}
function createString ($id, $chars) // THE ISSUE <---
{
    $length = getLength($id, $chars);
    //echo "LENGTH : ".$length."<br/><br/>";
    $string = "";
    for($i = 0; $i < $length; $i++)
    {
        $a = round(($id - 1)/pow($length, $i)); // THE ISSUE <-----
        $local = local($a, strlen($chars));
        $string = $chars{$local - 1}." : ".$string;
    }
    return $string;
}
function local ($num, $max)
{
    $num += $max;
    while($num > $max)
    {
        $num -= $max;
    }
    return $num;
}
/*
 get the length of the output by inputing the "in" and defining the possible characters
*/
function getLength ($id, $chars)
{
    $charNUM = 1;
    $LR = -1;
    $HR = 0;
    while(true)
    {
        $LR = $HR;
        $HR = pow(strlen($chars), $charNUM) + $LR;
        $LR += 1;
        //echo $LR." : ".$HR." : ".$charNUM."<br/>";
        if($id >= $LR && $id <= $HR)
        {
            return $charNUM;
        }
        if($id < $LR)
        {
            return false;
        }
        $charNUM ++;
    }
}

那将输出:
B : 
A : 
A : B : 
B : A : 
B : B : 
A : A : 
A : B : B : 
A : B : A : 
A : A : B : 
A : A : A : 
A : A : B : 
A : B : A : 
A : B : B : 
A : B : A : 
B : A : B : B : 
B : A : B : A : 
B : A : B : B : 
B : A : B : A : 
B : A : A : B : 
B : A : A : A : 
B : A : A : B : 
B : A : A : A : 
B : A : B : B : 
B : A : B : A : 
B : B : B : B : 
B : B : B : A : 
B : B : A : B : 
B : B : A : A : 
B : B : A : B : 
B : B : A : A : 
B : B : A : B : B : 
B : B : A : B : A : 
B : B : A : B : B : 
B : B : A : A : A : 
B : B : A : A : B : 
B : B : A : A : A : 
B : B : A : A : B : 
B : B : A : A : A : 
B : B : B : B : B : 
B : B : B : B : A : 
B : B : B : B : B :

等等,但是它有重复。我在使用createString()函数时遇到了问题。我想要在没有预先计算的情况下访问暴力破解密码表中某个位置的密码。我不想要一个预先计算的数组,只想访问其中的一个点。


不要像这样重复,例如:AAA和AAA,AAA = AAA - Patrick Lorio
我理解的是否正确:您想在一个系统中呈现数字,其中您通过字符串定义您的数字。因此,您系统的基数将是字符串的长度,第i位数字将是字符串中第i个位置的字符? - Nobody moving away from SE
在代码中,我有标签//<- ISSUE的地方是编译那个想法的地方。 - Patrick Lorio
1
你应该将你的解决方案发布为一个答案并接受它。 - Alex Turpin
你的解决方案给了我(http://ideone.com/Fh4tR):`A,B,BA,BB,AA,AB,ABA,ABB,AAA,BAB,BBA,BBB ...`,所以它似乎不符合你的期望输出。 - Nobody moving away from SE
3个回答

5
我将在这里发布用于将任何正整数转换为给定正整数进制(> 1)系统的代码,并返回每个数字的值。
function convert($number, $base)
{
        $return = array();
        do{
                $return[] = $number % $base;
                $number = floor($number / $base);
        }while($number != 0);
        return $return;
}

所以,您将按以下方式调用此函数:
function createString($i, $base)
{
        $res = convert($i, strlen($base));
        $str = "";
        foreach($res as $digit)
        {
                $str = $base[$digit] . $str;
        }
        return $str;
}

请试用一下。它的格式与您的输出略有不同,但应该是可读的。

以下是基于“AB”的一些示例输出:

0 -> A    
1 -> B
2 -> BA
3 -> BB
4 -> BAA
5 -> BAB
6 -> BBA
7 -> BBB
8 -> BAAA
9 -> BAAB
10-> BABA
11-> BABB
12-> BBAA
13-> BBAB
14-> BBBA
15-> BBBB

2
请注意,这并不能为您提供所需结果中表示的输出,因为您的输出不是基于2进制计数。 - Nobody moving away from SE

3

好的老递归

$string = "AB";
$characters = str_split($string, 1);

function mutate ($characters, $count) {
  var_dump($characters);

  if (!$count) return $characters;

  $result = $tmp = mutate($characters, $count -1);

  foreach ($characters as $char) {
    foreach ($tmp as $current) {
      $result[] = $current . $char;
    }
  }
  return $result;
}

1
你好,我尝试了你的代码,看起来非常不错。我用它尝试了7个字母,但出现了致命错误,所有内存都被耗尽了,所以我设置了更大的内存,结果导致我的电脑崩溃了。这是非常沉重的一段代码。 - zarcel
@zarcel 哦哈,好久不见 ^^ 首先可能是由于您的设置引起的:也许内存限制太小了(没有用),算法可能会在内存中创建大量字符串,因此这更多地导致了原始问题:只是想要太多东西。您可以使用数据库将当前不需要的字符串推迟到以后再使用。 - KingCrunch
1
而且你需要无限的内存。 - e-info128

3

解决方案:

function id_encode($id, $chars) {
    $len = strlen($chars);
    $i = 1;
    $str = array();
    while ($id >= 0) {
        $str[] = $chars[ $id / pow($len, $i - 1) % $len ];
        $id -= pow($len, $i);
        $i++;
    }
    return strrev(implode('', $str));
}
function id_decode($str, $chars) {
    $len = strlen($chars);
    $chars = array_flip(str_split($chars));
    $strs = str_split(strrev($str));
    $i = 0;
    foreach ($strs as $key => $char) {
        if (!$i) {
            $id = $chars[ $char ];
        }
        else {
            $id += pow($len, $i) * ($chars[ $char ] + 1);
        }
        $i++;
    }
    return $id;
}

例子:

$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';

$id = 42599293;

$string = id_encode($id, $chars);
echo 'id:          ' . $id . PHP_EOL;
echo 'id_encode(): ' . $string . PHP_EOL;
echo 'id_decode(): ' . id_decode($string, $chars) . PHP_EOL;

输出:

id:          42599293
id_encode(): bHFm9
id_decode(): 42599293

例子2:

$chars = 'AB';
$len = strlen($chars);

for ($i = 0; $i < 50; $i++) {
    if ($i) {
        if (!($i % $len)) {
            echo PHP_EOL;
        }
        else {
            echo ', ';
        }
    }
    $str = id_encode($i, $chars);
    $id = id_decode($str, $chars);
    echo $i . '=' . $str . '=' . $id;
}

输出 2:

0=A=0, 1=B=1
2=AA=2, 3=AB=3
4=BA=4, 5=BB=5
6=AAA=6, 7=AAB=7
8=ABA=8, 9=ABB=9
10=BAA=10, 11=BAB=11
12=BBA=12, 13=BBB=13
14=AAAA=14, 15=AAAB=15
16=AABA=16, 17=AABB=17
18=ABAA=18, 19=ABAB=19
20=ABBA=20, 21=ABBB=21
22=BAAA=22, 23=BAAB=23
24=BABA=24, 25=BABB=25
26=BBAA=26, 27=BBAB=27
28=BBBA=28, 29=BBBB=29
30=AAAAA=30, 31=AAAAB=31
32=AAABA=32, 33=AAABB=33
34=AABAA=34, 35=AABAB=35
36=AABBA=36, 37=AABBB=37
38=ABAAA=38, 39=ABAAB=39
40=ABABA=40, 41=ABABB=41
42=ABBAA=42, 43=ABBAB=43
44=ABBBA=44, 45=ABBBB=45
46=BAAAA=46, 47=BAAAB=47
48=BAABA=48, 49=BAABB=49

Credit for id_encode()归功于@PatrickLorio。 id_decode()是我自己构建的,首先手动计算: enter image description here 之后,我认为可以通过取id的n次方根来优化id_encode()...也许我会找时间检查一下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接