Skip to content

Commit

Permalink
port zxcvbn v4.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vvatanabe committed Oct 29, 2016
1 parent daa9073 commit 7e00e3f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
51 changes: 39 additions & 12 deletions src/main/java/com/nulabinc/zxcvbn/Scoring.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public static Strength mostGuessableMatchSequence(String password, List<Match> m
for (Match m : matches) {
matchesByJ.get(m.j).add(m);
}
for(List<Match> lst : matchesByJ) {
Collections.sort(lst, new Comparator<Match>() {
@Override
public int compare(Match m1, Match m2) {
return m1.i - m2.i;
}
});
}
final Optimal optimal = new Optimal(n);
for (int k = 0; k < n; k++) {
for(Match m :matchesByJ.get(k)) {
Expand All @@ -44,7 +52,8 @@ public static Strength mostGuessableMatchSequence(String password, List<Match> m
bruteforceUpdate(password, k, optimal, excludeAdditive);
}
List<Match> optimalMatchSequence = unwind(n, optimal);
double guesses = password.length() == 0 ? 1 : optimal.g.get(n - 1);
Integer optimalL = optimalMatchSequence.size();
double guesses = password.length() == 0 ? 1 : optimal.g.get(n - 1).get(optimalL);
Strength strength = new Strength();
strength.setPassword(password);
strength.setGuesses(guesses);
Expand All @@ -59,16 +68,30 @@ private static void update(String password, Match m, int l, Optimal optimal, boo
if (l > 1) {
pi *= optimal.pi.get(m.i - 1).get(l - 1);
}
if (Double.isInfinite(pi)) {
pi = Double.MAX_VALUE;
}
double g = factorial(l) * pi;
if (Double.isInfinite(g)) {
g = Double.MAX_VALUE;
}
if (!excludeAdditive) {
g += Math.pow(MIN_GUESSES_BEFORE_GROWING_SEQUENCE, l - 1);
if (Double.isInfinite(g)) {
g = Double.MAX_VALUE;
}
}
if (g < optimal.g.get(k)) {
optimal.g.set(k, g);
optimal.l.set(k, l);
optimal.m.get(k).put(l, m);
optimal.pi.get(k).put(l, pi);
for (Map.Entry<Integer, Double> competing : optimal.g.get(k).entrySet()) {
if (competing.getKey() > l) {
continue;
}
if (competing.getValue() <= g) {
return;
}
}
optimal.g.get(k).put(l, g);
optimal.m.get(k).put(l, m);
optimal.pi.get(k).put(l, pi);
}

private static void bruteforceUpdate(String password, int k, Optimal optimal, boolean excludeAdditive) {
Expand All @@ -94,7 +117,14 @@ private static List<Match> unwind(int n, Optimal optimal) {
List<Match> optimalMatchSequence = new ArrayList<>();
int k = n - 1;
if (0 <= k) {
int l = optimal.l.get(k);
Integer l = null;
Double g = Double.POSITIVE_INFINITY;
for (Map.Entry<Integer, Double> candidate : optimal.g.get(k).entrySet()) {
if (candidate.getValue() < g) {
l = candidate.getKey();
g = candidate.getValue();
}
}
while (k >= 0) {
Match m = optimal.m.get(k).get(l);
optimalMatchSequence.add(0, m);
Expand Down Expand Up @@ -122,16 +152,13 @@ private static class Optimal {

public final List<Map<Integer, Double>> pi = new ArrayList<>();

public final List<Double> g = new ArrayList<>();

public final List<Integer> l = new ArrayList<>();
public final List<Map<Integer, Double>> g = new ArrayList<>();

public Optimal(int n) {
for (int i = 0; i < n; i++) {
m.add(new HashMap<Integer, Match>());
pi.add(new HashMap<Integer, Double>());
g.add(Double.POSITIVE_INFINITY);
l.add(0);
g.add(new HashMap<Integer, Double>());
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/com/nulabinc/zxcvbn/guesses/DateGuess.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ public class DateGuess extends BaseGuess {
public double exec(Match match) {
double yearSpace = Math.max(Math.abs(match.year - REFERENCE_YEAR), MIN_YEAR_SPACE);
double guesses = yearSpace * 365;
// TEST
// if (match.hasFullYear) {
// guesses *= 2;
// }
if (match.separator != null) guesses *= 4;
return guesses;
}
Expand Down

0 comments on commit 7e00e3f

Please sign in to comment.