On Fri, Dec 31, 2010 at 2:02 AM, Peter Lind <peter.e.l...@gmail.com> wrote:
>
> On Dec 31, 2010 6:20 AM, "Tommy Pham" <tommy...@gmail.com> wrote:
>>
>> Hi folks,
>>
>> With the recent thread about password & security, I wrote a small quick
>> script to generate a random or all possible passwords based on certain
>> parameters for a brute force use.  On a very long running execution for a
>> complex password in length with full use of the keys (94 characters),
>> including upper case, the script seems to consumes more memory (shown in
>> Windows task manager) as time progress.  Below are snippets from the
>> script
>> file that does the workload:
>>
>> while (!$this->isMax())
>> {
>>        for ($b = 0; $b <= $this->pwdLength; $b++)
>>        {
>>                if ($this->counter[$b] < $this->max)
>>                {
>>                        $this->pwd[$b] =
>> $this->charList[$this->counter[$b]];
>>                        $this->counter[$b]++;
>>                        break;
>>                }
>>                else
>>                {
>>                        $this->counter[$b] = 1;
>>                        $this->pwd[$b] = $this->charList[0];
>>                }
>>        }
>> }
>>
>> private function isMax()
>> {
>>        for ($a = $this->pwdLength-1; $a>=0; $a--)
>>        {
>>                if ($this->counter[$a] < $this->max) return false;
>>        }
>>        return true;
>> }
>>
>> Could someone please tell me why the above code consumes additional memory
>> as time progress for the execution of the while loop?  Researching PHP GC
>> on
>> google didn't shed light on problem.  Generating all possible combinations
>> for 20 length with 94 possibilities each, the script easily consumes more
>> than 1GB RAM in few minutes.  BTW, gc_enabled() reports on.
>>
>> Thanks,
>> Tommy
>>
>>
>
> Are you storing or throwing away the passwords? Also, lots of code is
> missing from that post, no idea if you've got a memory leak in the rest of
> the code
>
> Regards
> Peter

Hi Peter,

Thanks for the reply.  After I sent the e-mail last night, I did a
little debugging.  As it turns out, xdebug was the culprit.  I gotta
remember to disable xdebug while coding...  Anyway, here's the full
code.  Anyone is welcome to use it.

$timeStart = microtime(true);

//set_time_limit(0);
ini_set('max_execution_time', 0);
ini_set('memory_limit', -1);
class PwdGen
{
        const ALPHA_LOWER = 'abcdefghijklmnopqrstuvwxyz';
        const ALPHA_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        const NUMERIC = '0123456789';
        const SPECIALS = '!...@#$%^&*()`~-_=+[]\{}|;:\'",./<>?';
        private $chars;
        private $charList;
        private $max;
        private $pwdLength;
        private $pwdList; // array
        private $pwd;
        private $counter; // array
        private $insertDb = false;

        public function __construct($pwdLength = 8, $useUpper = true,
$useNumeric = true, $useSpecials = true, $insertDb = true, $specials =
'')
        {
                $this->insertDb = $insertDb;
                $this->pwdLength = intval($pwdLength);
                $this->chars = self::ALPHA_LOWER;
                if ($useUpper) $this->chars .= self::ALPHA_UPPER;
                if ($useNumeric) $this->chars .= self::NUMERIC;
                if ($useSpecials) $this->chars .= empty($specials) ? 
self::SPECIALS
: $specials;
        }
        private function init()
        {
                $this->charList = str_split($this->chars, 1);
                $this->max = sizeof($this->charList);
                $this->pwd = str_split(str_repeat($this->charList[0], 
$this->pwdLength), 1);

                $this->pwdList = array(); // array
                $this->counter = array();
                for ($a = 0; $a < $this->pwdLength; $a++)
                        $this->counter[$a] = 1;
                $this->counter[$this->pwdLength-1] = 0;
        }
        public function setPasswordLength($pwdLength)
        {
                $this->pwdLength = intval($pwdLength);
        }
        public function setUseChars($useUpper = true, $useNumeric = true,
$useSpecials = true, $specials = '')
        {
                $this->chars = self::ALPHA_LOWER;
                if ($useUpper) $this->chars .= self::ALPHA_UPPER;
                if ($useNumeric) $this->chars .= self::NUMERIC;
                if ($useSpecials) $this->chars .= empty($specials) ? 
self::SPECIALS
: $specials;
        }
        public function getRandom()
        {
                $this->init();
                for ($a = 0; $a < $this->pwdLength; $a++)
                        $this->pwd[$a] = $this->charList[rand(0, $this->max - 
1)];
                $pwd = implode('', $this->pwd);
                $output = $this->max.': '.$this->chars.' ('.pow($this->max,
$this->pwdLength).') '.PHP_EOL.$pwd.PHP_EOL;
                return $output;
        }
        public function getAll($continue = true)
        {
                $this->init();
                $sql = 'INSERT INTO `password`(`guid`, `length`, `password`,
`counter`, `date_added`) VALUES (BinUUID(), '.$this->pwdLength.', ?,
?, now())';

                $pwd = '';
                $counter = '';
                $output = $this->max.': '.$this->chars.' ('.pow($this->max,
$this->pwdLength).')'.PHP_EOL;

                if ($this->insertDb)
                {
                        $db = new mysqli('127.0.0.1', 'user', 'pass', 
'brute_force');
                        if (mysqli_connect_errno()) {
                            printf("Connect failed: %s\n", 
mysqli_connect_error());
                            exit();
                        }

                        $stmt = $db->prepare($sql);
                        if ($stmt === false) {
                            printf("Prepare failed: %s\n", $db->error);
                            $stmt->close();
                            $db->close();
                            exit();
                        }
                        if ($stmt->bind_param('ss', $pwd, $counter) === false)
                        {
                            printf("Bind Param failed: %s\n", $stmt->error);
                            $stmt->close();
                            $db->close();
                            exit();
                        }
                }
                while (!$this->isMax())
                {
                        for ($b = $this->pwdLength - 1; $b >= 0; $b--)
                        {
                                if ($this->counter[$b] < $this->max)
                                {
                                        $this->pwd[$b] = 
$this->charList[$this->counter[$b]];
                                        $this->counter[$b]++;
                                        break;
                                }
                                else
                                {
                                        $this->counter[$b] = 1;
                                        $this->pwd[$b] = $this->charList[0];
                                }
                        }

                        $pwd = implode('', $this->pwd);
//                      $this->pwdList[] = $pwd;

                        if ($this->insertDb)
                        {
                                //$counter = json_encode($this->counter);
                                $counter = '[';
                                for ($c = 0; $c < $this->pwdLength; $c++)
                                {
                                        $counter .= sprintf('%02d', 
$this->counter[$c]);
                                        if ($c+1 < $this->pwdLength) $counter 
.= ',';
                                }
                                $counter .= ']';
                                if ($stmt->execute() === false)
                                {
                                    printf("Execute failed: %s\n", 
$stmt->error);
                                    $stmt->close();
                                    $db->close();
                                    exit();
                                }
                        }
//                      $output .= $pwd.' ';
//                      $output .= implode(':', $this->counter).' ';
//                      $output .= PHP_EOL;
                }
                if ($this->insertDb)
                {
                        $stmt->close();
                        $db->close();
                }
                return $output;
        }
        private function isMax()
        {
                for ($m = 0; $m < $this->pwdLength; $m++)
                        if ($this->counter[$m] < $this->max) return false;

                return true;
        }
}
$output = '<pre>';
$pg = new PwdGen();

$dbMax = 25;

if (!empty($_GET['min']) && !empty($_GET['max']))
{
        $min = intval($_GET['min']);
        $max = intval($_GET['max']);
        if ($max > $dbMax) $max = $dbMax;
} else
{
        $min = 4;
        $max = 5;
}

if (!empty($_GET['get']) && $_GET['get'] == 'all')
{
        if (empty($_GET['length']))
        {
                for ($i = $min; $i <= $max; $i++)
                {
                        $_POST['length'] = $i;
                        $pg->setPasswordLength($i);
                        $output .= $pg->getAll();
                }
        }
        else
        {
                $i = intval($_GET['length']);
                $_POST['length'] = $i;
                $pg->setPasswordLength($i);
                $output .= $pg->getAll();
        }
}
else
{
        if (empty($_POST['useUpper'])) $useUpper = false;
        else $useUpper = true;
        if (empty($_POST['useNumeric'])) $useNumeric = false;
        else $useNumeric = true;
        if (empty($_POST['useSpecials'])) $useSpecials = false;
        else $useSpecials = true;
        if (empty($_POST['specials'])) $specials = '';
        else $specials = trim($_POST['specials']);
        $pg->setUseChars($useUpper, $useNumeric, $useSpecials, $specials);

        if (!empty($_POST['length'])) 
$pg->setPasswordLength(intval($_POST['length']));
        $output .= $pg->getRandom();
}

$lengthList = 'Length: <select size="1" name="length">';
for ($l = 3; $l <= $dbMax; $l++)
        if (!empty($_POST['length']) && $_POST['length'] == $l) $lengthList
.= '<option selected="selected">'.$l.'</option>';
        else $lengthList .= '<option>'.$l.'</option>';
$lengthList .= '</select>';

$htmlForm = '<form method="post" enctype="multipart/form-data">'.PHP_EOL;
$htmlForm .= 'Upper case: <input type="checkbox" checked="checked"
name="useUpper" /> '.PHP_EOL;
$htmlForm .= 'Numbers: <input type="checkbox" checked="checked"
name="useNumeric" /> '.PHP_EOL;
$htmlForm .= 'Specials - symbols: <input type="checkbox"
checked="checked" name="useSpecials" /> '.PHP_EOL;
$htmlForm .= 'Custom: <input name="specials" maxlength="30" size="30"
value="'.$specials.'" /> '.PHP_EOL;
$htmlForm .= $lengthList.PHP_EOL;
$htmlForm .= '<input type="submit" value="Get Random" /></form>'.PHP_EOL;
$htmlForm .= '<form method="get"
enctype="application/x-www-form-urlencoded">'.PHP_EOL;
$htmlForm .= '<input name="get" type="hidden" value="all" /> '.PHP_EOL;
$htmlForm .= $lengthList.PHP_EOL;
$htmlForm .= '<input type="submit" value="Get All" /></form>'.PHP_EOL;

$timeEnd = microtime(true);
$timeExec = $timeEnd - $timeStart;
$output .= PHP_EOL.PHP_EOL.getmypid().' executed: '.$timeExec.PHP_EOL.'</pre>';

echo '<html><body>'.$htmlForm.$output.'</body></html>';


Disclaimer:  The above code is intended for scientific research.
You're responsible for your action.

Happy New Year!!
Tommy

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to