Skip to content

Instantly share code, notes, and snippets.

@jskrivseth
Created August 29, 2020 15:25
Show Gist options
  • Save jskrivseth/df45a347590048d593c3e739872f51c0 to your computer and use it in GitHub Desktop.
Save jskrivseth/df45a347590048d593c3e739872f51c0 to your computer and use it in GitHub Desktop.
<?php
/**
* @param string $charset the entire set of characters to permute
* @param array|int[] $ring an array of counters representing the character pointed to by each element of the cipher ring
* @return Generator
*/
function permute($charset, array $ring = [0])
{
while (count($ring) <= strlen($charset)) {
//compile the current permutation using the ring state
$permutation = [];
foreach ($ring as $i => $char) {
$permutation[$i] = $charset[$char];
}
yield implode('', $permutation); //convert to string and yield
//rotate the ring by incrementing the right-mode digit
$end = count($ring) - 1;
$ring[$end]++;
//working from right to left, carry all overflow to the left
for ($i = count($ring) - 1; $i >= 0; $i--) {
//if the digit overflows
if ($ring[$i] > strlen($charset) - 1) {
//reset it to zero
$ring[$i] = 0;
//and carry the overflow
if (isset($ring[$i - 1])) {
$ring[$i - 1]++;
} else {
//if we've overflowed to the start, prepend a position to the ring
array_unshift($ring, 0);
}
} else {
break; // we didn't overflow in the bit, so no need to carry any overflow left
}
}
}
}
$charset = '1234567890abcdefghijklmnopqrstuvwxyz';
foreach (permute($charset) as $password) {
//do something with $password
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment