private function repeatedCharacters($password, &$strength) { for ($i = 0; $i < $strength->nLength; $i++) { $bCharExists = false; $char = UTF8Utils::utf8Substr($password, $i, 1); for ($j = 0; $j < $strength->nLength; $j++) { if ($i !== $j && $char === UTF8Utils::utf8Substr($password, $j, 1)) { $bCharExists = true; /* Calculate increment deduction based on proximity to identical characters Deduction is incremented each time a new match is discovered Deduction amount is based on total password length divided by the difference of distance between currently selected match */ $strength->sRepChar += abs($strength->nLength / ($j - $i)); } } if ($bCharExists) { $strength->nRepChar++; $nUnqChar = $strength->nLength - $strength->nRepChar; $strength->sRepChar = $nUnqChar ? ceil($strength->sRepChar / $nUnqChar) : ceil($strength->sRepChar); } if ($i < $strength->nLength - 2) { if (preg_match('/[a-zA-Z]/', $char)) { $char_value = ord(strtoupper($char)); $next_char = UTF8Utils::utf8Substr($password, $i + 1, 1); $next_char_value = ord(strtoupper($next_char)); if ($char_value !== 89 && $char_value !== 90 && $char_value + 1 === $next_char_value) { $next2_char = UTF8Utils::utf8Substr($password, $i + 2, 1); $next2_char_value = ord(strtoupper($next2_char)); if ($next_char_value + 1 === $next2_char_value) { $strength->nSeqAlpha++; $strength->nSeqChar++; } } elseif ($char_value !== 65 && $char_value !== 66 && $char_value - 1 === $next_char_value) { $next2_char = UTF8Utils::utf8Substr($password, $i + 2, 1); $next2_char_value = ord(strtoupper($next2_char)); if ($next_char_value - 1 === $next2_char_value) { $strength->nSeqAlpha++; $strength->nSeqChar++; } } } elseif (preg_match('/[0-9]/', $char)) { $next_char = (int) UTF8Utils::utf8Substr($password, $i + 1, 1); if ((int) $char !== 8 && (int) $char !== 9 && (int) $char + 1 === $next_char) { $next2_char = (int) UTF8Utils::utf8Substr($password, $i + 2, 1); if ($next_char + 1 === $next2_char) { $strength->nSeqNumber++; $strength->nSeqChar++; } } elseif ((int) $char !== 0 && (int) $char !== 1 && (int) $char - 1 === $next_char) { $next2_char = (int) UTF8Utils::utf8Substr($password, $i + 2, 1); if ($next_char - 1 === $next2_char) { $strength->nSeqNumber++; $strength->nSeqChar++; } } } } } }
/** * Returns the current column of the current line that the tokenizer is at. * * Newlines are column 0. The first char after a newline is column 1. * * @return int * The column number. */ public function columnOffset() { // Short circuit for the first char. if ($this->char == 0) { return 0; } // strrpos is weird, and the offset needs to be negative for what we // want (i.e., the last \n before $this->char). This needs to not have // one (to make it point to the next character, the one we want the // position of) added to it because strrpos's behaviour includes the // final offset byte. $backwardFrom = $this->char - 1 - strlen($this->data); $lastLine = strrpos($this->data, "\n", $backwardFrom); // However, for here we want the length up until the next byte to be // processed, so add one to the current byte ($this->char). if ($lastLine !== FALSE) { $findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine); } else { // After a newline. $findLengthOf = substr($this->data, 0, $this->char); } return UTF8Utils::countChars($findLengthOf); }