tags:

views:

76

answers:

3
$chars = array
(
    ' ',
    '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    ':', ';', '<', '=', '>', '?', '`',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    '{', '|', '}', '~'
);

With the characters from the $chars array, I would like to find all possible combinations, for a length up to $n.

**For Example**:
It should start off with ' ', and then go to '!'.
Once it gets to the end of the $chars array (`~`) it should add on another charter.
Run though those combinations ('! ', '" ', ... '~ ', ' !' ... '~~', '   ', ect).
And then just keep on going ... 
A: 

This function will take an array $permutation only containing elements from another array $set and generate the next permutation up to a maximum length of $max.

function next_permutation($permutation, $set, $max)
{
    if (array_unique($permutation) === array(end($set)))
    {
        if (count($permutation) === $max)
        {
            return FALSE;
        }

        return array_fill(0, count($permutation) + 1, $set[0]);
    }

    foreach (array_reverse($permutation, TRUE) as $key => $value)
    {
        if ($value !== end($set))
        {
            $permutation[$key] = $set[array_search($value, $set) + 1];
            break;
        }

        $permutation[$key] = $set[0];
    }

    return $permutation;
}

The function could then be used in a way like this, to iterate over each possible permutation and check it against a hashed password.

$set         = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
$max         = 3;
$permutation = array($set[0]);
$password    = '403926033d001b5279df37cbbe5287b7c7c267fa';

do {
    $string = implode('', $permutation);

    if (sha1($string) === $password)
    {
        echo 'Password found: "'.$string.'"';
        break;
    }
} while ($permutation = next_permutation($permutation, $set, $max));

This would print Password found: "lol"

Zackman
First off, I'm sorry for not explaining myself and my idea's more thoroughly. [I'll never find a programming language that frees me from the burden of clarifying my ideas.](http://xkcd.com/568/) I wish the value to be a string, that is edited and changed on each run through a loop, so that I can hash and test it's hashed value against that of another hash to find out if it's thats the users' password or not.
Mark Tomlin
I've updated the function accordingly. The function takes an array instead of a string, though, for more flexibility (ie. if you wanted to use a set with multi-character elements).
Zackman
A: 

If You want to find just a number of possible combinations, it would be combination - permutation math - You have to raise your length $n to a power of elements in Your array. In Php that would be:

echo pow($n, count($chars)); 

where $n - your combination length.

Math reference: combinations - permutations

P.S. Salute Zackmans solution, but I wonder if it (and any others in that matter) doesn't cause PHP script timeout because of the scope of the problem.

arunas_t
Should it be `echo pow(count($chars), $n);`?
Zackman
No, exactly no. I have given the link, it's example 2, page 259. The base is $n. I wish there would be more people appreciating answers instead of just criticizing because it's sometimes boring to get into a subject, present an answer and not get a single point.
arunas_t
From Mark's example it's seen that repetitions are allowed.
arunas_t
@Arunas, unless I made a mistake there really should be no repetitions as each new value would be different from the last in one way or another. Also, I would agree that this would cause the default 30 second script limit to be passed, but I'm using this via Command Line, so the it runs until the program ends (or indefinitely.)
Mark Tomlin
By repetitions I meant that symbols could repeat in your line, like 'aaa', 'bbbcde', and You indicated that in Your example: >>Run though those combinations ('! ', '" ', ... '~ ', ' !' ... '~~', ' ', ect). Look at thease 2 '~~'
arunas_t
But in the referenced example (in which there are 26 letters to choose from and the word-length `$n` is 3) the calculation is `26^3. So the number of letters is the base raised to the power of length `$n`.
Zackman
For example, lets say there are 3 possible letters (A, B, C) and the word length is one. Now, logically, in this scenario there are 3 possible combinations. Using `pow($n, count($chars))` would give the answer 1, while `pow(count($chars), $n)` would be 3. I wasn't criticizing your answer, and don't think it's a boring subject. :)
Zackman