Calculate password strength via non-overlapping minimum entropy patterns.

@param string $password   Password to measure
@param array  $userInputs Optional user inputs

@return array Strength result array with keys:
password
entropy
match_sequence
score
14347
public function passwordStrength($password, array $userInputs = [])
    {
        $timeStart = microtime(true);
        if ('' === $password) {
            $timeStop = microtime(true) - $timeStart;

            return $this->result($password, 0, [], 0, ['calc_time' => $timeStop]);
        }

        // Get matches for $password.
        $matches = $this->matcher->getMatches($password, $userInputs);

        // Calcuate minimum entropy and get best match sequence.
        $entropy = $this->searcher->getMinimumEntropy($password, $matches);
        $bestMatches = $this->searcher->matchSequence;

        // Calculate score and get crack time.
        $score = $this->scorer->score($entropy);
        $metrics = $this->scorer->getMetrics();

        $timeStop = microtime(true) - $timeStart;
        // Include metrics and calculation time.
        $params = array_merge($metrics, ['calc_time' => $timeStop]);

        return $this->result($password, $entropy, $bestMatches, $score, $params);
    }
744973
public function checkUserCredentials($username, $password)
	{
		// allow authentication via email, just like in the hub
		if (strpos($username, '@'))
		{
			$username = $this->getUsernameFromEmail($username);
		}

		// use hubzero password library to compare stored password with sent password
		$match = Password::passwordMatches($username, $password, true);

		// return if match was found
		return (bool) $match;
	}
850684
public static function equals($knownString, $userInput)
    {
        if (!is_string($knownString)) {
            $knownString = (string)$knownString;
        }

        if (!is_string($userInput)) {
            $userInput = (string)$userInput;
        }

        if (function_exists('hash_equals')) {
            return hash_equals($knownString, $userInput);
        }

        $knownLength = mb_strlen($knownString);

        if (mb_strlen($userInput) !== $knownLength) {
            return false;
        }

        $result = 0;

        for ($i = 0; $i < $knownLength; ++$i) {
            $result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
        }

        return 0 === $result;
    }
759441
public static function match($password, array $userInputs = [])
    {
        // Translate l33t password and dictionary match the translated password.
        $map = static::getSubstitutions($password);
        $indexSubs = array_filter($map);
        if (empty($indexSubs)) {
            return [];
        }
        $translatedWord = static::translate($password, $map);

        $matches = [];
        $dicts = static::getRankedDictionaries();
        foreach ($dicts as $name => $dict) {
            $results = static::dictionaryMatch($translatedWord, $dict);
            foreach ($results as $result) {
                // Set substituted elements.
                $result['sub'] = [];
                $result['sub_display'] = [];
                foreach ($indexSubs as $i => $t) {
                    $result['sub'][$password[$i]] = $t;
                    $result['sub_display'][] = "{$password[$i]} -> ${t}";
                }
                $result['sub_display'] = implode(', ', $result['sub_display']);
                $result['dictionary_name'] = $name;
                // Replace translated token with orignal password token.
                $token = substr($password, $result['begin'], $result['end'] - $result['begin'] + 1);
                $matches[] = new static($password, $result['begin'], $result['end'], $token, $result);
            }
        }

        return $matches;
    }
690768
public function check($password)
    {
        $this->_analyze($password);

        $this->_score = 0;

        // First character is 4 bits of entropy
        if ($this->_length > 0) {
            $this->_score += 4;
        }

        // The next seven characters are 2 bits of entropy
        if ($this->_length > 1) {
            $this->_score += strlen(substr($password, 1, 7)) * 2;
        }

        // Characters 9 through 20 are 1.5 bits of entropy
        if ($this->_length > 8) {
            $this->_score += strlen(substr($password, 8, 12)) * 1.5;
        }

        // Characters 21 and beyond are 1 bit of entropy
        if ($this->_length > 20) {
            $this->_score += strlen(substr($password, 20));
        }

        // Bonus of 6 bits if upper, lower, and non-alpha characters are used
        if ($this->_getClassCount(self::CLASS_UPPER) > 0 && $this->_getClassCount(self::CLASS_LOWER)) {
            if ($this->_getClassCount(self::CLASS_NUMBER) > 0 || $this->_getClassCount(self::CLASS_SYMBOL)) {
                $this->_score += 6;
            }
        }

        return $this->_score;
    }
1045299
private function getUserPasswordDigest(PKEncryptionEnabledUserInterface $user)
    {
        $passwordDigest = $user->getPasswordDigest();

        if (!$passwordDigest) {
            $password = $user->getPlainPassword();

            if ($password) {
                $salt = $user->getSalt();
                $passwordDigest = $this->cryptographyProvider->getPasswordDigest($password, $salt);
            }
        }

        return $passwordDigest;
    }
160915
public static function changePassword($user = null, $password)
	{
		$passhash = self::getPasshash($password);

		return self::changePasshash($user, $passhash);
	}
489146
final protected function  _getPasswordEntropyDescription(){
        $entropyObj = $this->_getUdfEntropy();
        
        $description    = 'The password entropy requires at minimum, the following: ';
        $hasEntropy     = false;
        $isFirstEntropy = false;
        $concatenator   = '';
        
        if ($entropyObj['lowercase']['min_len'] > 0) {
            $lowercaseLen   = $entropyObj['lowercase']['min_len'];
            $description   .= " at least $lowercaseLen lowercase characters";
            $hasEntropy     = true;
            $isFirstEntropy = true;
        }
        
        if ($entropyObj['uppercase']['min_len'] > 0) {
            $isFirstEntropy = $isFirstEntropy === true?  false : true;
            $concatenator   = $isFirstEntropy === true ? ''    : ',';
            $uppercaseLen   = $entropyObj['uppercase']['min_len'];
            $description   .= "$concatenator at least $uppercaseLen uppercase characters";
            $hasEntropy     = true;     
        }
        
        if ($entropyObj['numeric']['min_len'] > 0) {
            $isFirstEntropy = $isFirstEntropy === true ? false : true;
            $concatenator   = $isFirstEntropy === true ? ''    : ',';
            $numericLen     = $entropyObj['numeric']['min_len'];
            $description   .= "$concatenator at least $numericLen numeric characters";
            $hasEntropy     = true;     
        }

        if ($entropyObj['special']['min_len'] > 0) {
            $isFirstEntropy = $isFirstEntropy === true ? false : true;
            $concatenator   = $isFirstEntropy === true ? ''    : ',';
            $specialLen     = $entropyObj['special']['min_len'];
            $description   .= "$concatenator at least $specialLen special characters";
            $hasEntropy     = true;     
        }
        
        if (!($hasEntropy === true)) {
            $description = 'There is no minimum password entropy policy in place';
        }
        
        return $description;
    }
138677
public function passwordChange($newPassword, $userID = null)
    {
        $hash = null;
        if (empty($userID)) {
            $userID = $this->getUserID();
        }
        if (!empty($userID)) {
            $hash = $this->encryptPassword($newPassword);

            $this->kontakt->insertToFlexiBee([
                'id' => $userID,
                'username' => $this->getUserLogin(),
                'password' => $hash,
//    'password@hash' => 'sha256',
//    'password@salt' => 'osoleno',
            ]);
            if ($this->kontakt->lastResponseCode == 201) {
                $this->kontakt->addStatusMessage('Password set', 'success');
                $this->kontakt->loadFromFlexiBee();
            } else {
                $hash = null;
                $this->kontakt->addStatusMessage('Password set failed',
                    'warning');
            }

            $this->addToLog('PasswordChange: '.$this->getDataValue($this->loginColumn).'@'.$userID.'#'.$this->getDataValue($this->myIDSColumn).' '.$hash);
            if ($userID == $this->getUserID()) {
                $this->setDataValue($this->passwordColumn, $hash);
            }
        }

        return $hash;
    }
1107451
public static function match($password, array $userInputs = [])
    {
        $matches = [];
        $dicts = static::getRankedDictionaries();
        if (!empty($userInputs)) {
            $dicts['user_inputs'] = [];
            foreach ($userInputs as $rank => $input) {
                $input_lower = strtolower($input);
                $rank = is_numeric($rank) ? $rank : count($dicts['user_inputs']);
                $dicts['user_inputs'][$input_lower] = max(1, $rank);
            }
        }
        foreach ($dicts as $name => $dict) {
            $results = static::dictionaryMatch($password, $dict);
            foreach ($results as $result) {
                $result['dictionary_name'] = $name;
                $matches[] = new static($password, $result['begin'], $result['end'], $result['token'], $result);
            }
        }

        return $matches;
    }
581376
public static function password_hash($password, $salt)
    {
        $app_auth_pepper = Config::get('security.auth_pepper', '');
        return sha1($password . $salt . $app_auth_pepper);
    }
1036740
public function sendGeneratedPassword(User $user, $password)
    {
        return $this->sendMessage(
            $user->email,
            $this->getNewPasswordSubject(),
            'new_password',
            ['user' => $user, 'password' => $password, 'module' => $this->module]
        );
    }
362222
public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->userPasswordEncoderFactory->isPasswordValid($user, $credentials->getPassword());
    }
1273131
function checkPassword(Userinfo $userinfo) {
		return $this->comparePassword($userinfo->password, $this->generateEncryptedPassword($userinfo));
	}
630545
def minimum_entropy_match_sequence(password, matches):
    
    bruteforce_cardinality = calc_bruteforce_cardinality(password) # e.g. 26 for lowercase
    up_to_k = [0] * len(password) # minimum entropy up to k.
    # for the optimal sequence of matches up to k, holds the final match (match['j'] == k). null means the sequence ends
    # without a brute-force character.
    backpointers = []
    for k in range(0, len(password)):
        # starting scenario to try and beat: adding a brute-force character to the minimum entropy sequence at k-1.
        up_to_k[k] = get(up_to_k, k-1) + lg(bruteforce_cardinality)
        backpointers.append(None)
        for match in matches:
            if match['j'] != k:
                continue
            i, j = match['i'], match['j']
            # see if best entropy up to i-1 + entropy of this match is less than the current minimum at j.
            up_to = get(up_to_k, i-1)
            candidate_entropy = up_to + calc_entropy(match)
            if candidate_entropy < up_to_k[j]:
                #print "New minimum: using " + str(match)
                #print "Entropy: " + str(candidate_entropy)
                up_to_k[j] = candidate_entropy
                backpointers[j] = match

    # walk backwards and decode the best sequence
    match_sequence = []
    k = len(password) - 1
    while k >= 0:
        match = backpointers[k]
        if match:
            match_sequence.append(match)
            k = match['i'] - 1
        else:
            k -= 1
    match_sequence.reverse()

    # fill in the blanks between pattern matches with bruteforce "matches"
    # that way the match sequence fully covers the password: match1.j == match2.i - 1 for every adjacent match1, match2.
    def make_bruteforce_match(i, j):
        return {
            'pattern': 'bruteforce',
            'i': i,
            'j': j,
            'token': password[i:j+1],
            'entropy': lg(math.pow(bruteforce_cardinality, j - i + 1)),
            'cardinality': bruteforce_cardinality,
        }
    k = 0
    match_sequence_copy = []
    for match in match_sequence:
        i, j = match['i'], match['j']
        if i - k > 0:
            match_sequence_copy.append(make_bruteforce_match(k, i - 1))
        k = j + 1
        match_sequence_copy.append(match)

    if k < len(password):
        match_sequence_copy.append(make_bruteforce_match(k, len(password) - 1))
    match_sequence = match_sequence_copy

    min_entropy = 0 if len(password) == 0 else up_to_k[len(password) - 1] # corner case is for an empty password ''
    crack_time = entropy_to_crack_time(min_entropy)

    # final result object
    return {
        'password': password,
        'entropy': round_to_x_digits(min_entropy, 3),
        'match_sequence': match_sequence,
        'crack_time': round_to_x_digits(crack_time, 3),
        'crack_time_display': display_time(crack_time),
        'score': crack_time_to_score(crack_time),
    }
1297066
public static function match($password, array $userInputs = [])
    {
        $matches = [];
        $groups = static::findAll($password, '/(19\\d\\d|200\\d|201\\d)/');
        foreach ($groups as $captures) {
            $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']);
        }

        return $matches;
    }
882912
protected function result($password, $entropy, $matches, $score, $params = [])
    {
        $r = [
            'password' => $password,
            'entropy' => $entropy,
            'match_sequence' => $matches,
            'score' => $score,
        ];

        return array_merge($params, $r);
    }