Exemple #1
0
function minimum_entropy_match_sequence($password, $matches)
{
    # e.g. 26 for lowercase
    $bruteforce_cardinality = calc_bruteforce_cardinality($password);
    # minimum entropy up to k.
    $up_to_k = array();
    # for the optimal sequence of matches up to k, holds the
    # final match (match.j == k). null means the sequence ends
    # w/ a brute-force character.
    $backpointers = array();
    $password_len = strlen($password);
    for ($k = 0; $k < $password_len; $k++) {
        # starting scenario to try and beat:
        # adding a brute-force character to the minimum entropy sequence at k-1.
        $up_to_k[$k] = _get_index($up_to_k, $k - 1) + logarithm($bruteforce_cardinality);
        $backpointers[$k] = NULL;
        foreach ($matches as $match) {
            if ($match['j'] !== $k) {
                continue;
            }
            $i = $match['i'];
            $j = $match['j'];
            # see if best entropy up to i-1 + entropy of this match
            # is less than the current minimum at j.
            $candidate_entropy = _get_index($up_to_k, $i - 1) + calc_entropy($match);
            if ($candidate_entropy < $up_to_k[$j]) {
                $up_to_k[$j] = $candidate_entropy;
                $backpointers[$j] = $match;
            }
        }
    }
    # walk backwards and decode the best sequence
    $match_sequence = array();
    $k = strlen($password) - 1;
    while ($k >= 0) {
        $match = $backpointers[$k];
        if ($match) {
            $match_sequence[] = $match;
            $k = $match['i'] - 1;
        } else {
            $k -= 1;
        }
    }
    $match_sequence = array_reverse($match_sequence);
    # 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.
    $make_bruteforce_match = function ($i, $j) use($password, $bruteforce_cardinality) {
        return array('pattern' => 'bruteforce', 'i' => $i, 'j' => $j, 'token' => _slice($password, $i, $j + 1), 'entropy' => logarithm(pow($bruteforce_cardinality, $j - $i + 1)), 'cardinality' => $bruteforce_cardinality);
    };
    $k = 0;
    $match_sequence_copy = array();
    foreach ($match_sequence as $match) {
        $i = $match['i'];
        $j = $match['j'];
        if ($i - $k > 0) {
            $match_sequence_copy[] = $make_bruteforce_match($k, $i - 1);
        }
        $k = $j + 1;
        $match_sequence_copy[] = $match;
    }
    if ($k < strlen($password)) {
        $match_sequence_copy[] = $make_bruteforce_match($k, strlen($password) - 1);
    }
    $match_sequence = $match_sequence_copy;
    # or 0 corner case is for an empty password ''
    if (isset($up_to_k[strlen($password) - 1])) {
        $min_entropy = $up_to_k[strlen($password) - 1];
    } else {
        $min_entropy = 0;
    }
    $crack_time = entropy_to_crack_time($min_entropy);
    # final result object
    $result = array('password' => $password, 'entropy' => round_to_x_digits($min_entropy, 3), 'match_sequence' => $match_sequence, 'crack_time_seconds' => round_to_x_digits($crack_time, 3), 'crack_time_display' => display_time($crack_time), 'score' => crack_time_to_score($crack_time));
    return $result;
}
function generic_list_siblings(&$app, $c)
{
    global $lang;
    $db =& $app->db;
    $def =& $db->def;
    $p =& $app->ui;
    $id = $app->arg('id');
    $id_last = $db->column($c->table, 'id_last', $id);
    $id_next = $db->column($c->table, 'id_next', $id);
    list($thisindex, $last) = _get_index($app, $c->table, $def->id_parent($c->table), $c->table, $id);
    if ($id_last) {
        $e = $app->event()->copy();
        $e->set_arg('id', $id_last);
        $p->link($lang['previous'], $e);
    }
    echo ' ' . sprintf($lang['x of y'], $thisindex, $last) . ' ';
    if ($id_next) {
        $e = $app->event()->copy();
        $e->set_arg('id', $id_next);
        $p->link($lang['next'], $e);
    }
}