On Fri, Dec 31, 2010 at 2:02 AM, Peter Lind <peter.e.lind@xxxxxxxxx> wrote: > > On Dec 31, 2010 6:20 AM, "Tommy Pham" <tommyhp2@xxxxxxxxx> 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