Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix the discrepancy in password guesses between zxcvbn and zxcvbn4j #151

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/main/java/com/nulabinc/zxcvbn/Guess.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.nulabinc.zxcvbn;

import com.nulabinc.zxcvbn.matchers.Match;
import java.util.Calendar;

public interface Guess {

public static final int BRUTEFORCE_CARDINALITY = 10;
public static final int MIN_SUBMATCH_GUESSES_SINGLE_CHAR = 10;
public static final int MIN_SUBMATCH_GUESSES_MULTI_CHAR = 50;
public static final int MIN_YEAR_SPACE = 20;
public static final int REFERENCE_YEAR = 2000;
public static final int REFERENCE_YEAR = Calendar.getInstance().get(Calendar.YEAR);

public double exec(Match match);
}
20 changes: 10 additions & 10 deletions src/main/java/com/nulabinc/zxcvbn/matchers/DateMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,13 @@ private Dmy mapIntsToDmy(int[] ints) {
if (over31 >= 2 || over12 == 3 || under1 >= 2) {
return null;
}
Map<Integer, int[]> possibleYearSplits = new HashMap<>();
possibleYearSplits.put(ints[2], Arrays.copyOfRange(ints, 0, 1 + 1));
possibleYearSplits.put(ints[0], Arrays.copyOfRange(ints, 1, 2 + 1));
for (Map.Entry<Integer, int[]> possibleYearSplitRef : possibleYearSplits.entrySet()) {
int y = possibleYearSplitRef.getKey();
int[] rest = possibleYearSplitRef.getValue();
int[][] possibleYearSplits = {
{ints[2], ints[0], ints[1]},
{ints[0], ints[1], ints[2]}
};
for (int[] split : possibleYearSplits) {
int y = split[0];
int[] rest = new int[] {split[1], split[2]};
if (DATE_MIN_YEAR <= y && y <= DATE_MAX_YEAR) {
Dm dm = mapIntsToDm(rest);
if (dm != null) {
Expand All @@ -274,12 +275,11 @@ private Dmy mapIntsToDmy(int[] ints) {
}
}
}
for (Map.Entry<Integer, int[]> possibleYearSplitRef : possibleYearSplits.entrySet()) {
int y = possibleYearSplitRef.getKey();
int[] rest = possibleYearSplitRef.getValue();
for (int[] split : possibleYearSplits) {
int[] rest = new int[] {split[1], split[2]};
Dm dm = mapIntsToDm(rest);
if (dm != null) {
y = twoToFourDigitYear(y);
int y = twoToFourDigitYear(split[0]);
return new Dmy(dm.day, dm.month, y);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/com/nulabinc/zxcvbn/JavaPortTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public static Iterable<Object[]> data() {
{"password@123"},
{"lkjhgfdsa"},
{"hGFd"},
{"2352523452bd dhf"},
{"23525"},
// the following password fails in version 4.4.1
// https://github.com/dropbox/zxcvbn/issues/174
//
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/com/nulabinc/zxcvbn/MatchingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,13 @@ public static Collection<Object[]> data() {
new ExpectedMatch("111504").separator("").year(2004).month(11).day(15)
});

data.add(
new Object[] {
"23525",
"matches as 23/5/2025, not 25/5/2023",
new ExpectedMatch("23525").separator("").year(2025).month(5).day(23)
});

return data;
}
}
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/com/nulabinc/zxcvbn/ScoringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -398,4 +398,52 @@ public void testL33tVariants() throws Exception {
0.0);
}
}

@RunWith(Parameterized.class)
public static class DateGuessTest {

private final String token;
private final int i;
private final int j;
private final String separator;
private final int year;
private final int month;
private final int day;
private final double expectedGuesses;

public DateGuessTest(
String token,
int i,
int j,
String separator,
int year,
int month,
int day,
double expectedGuesses) {
this.token = token;
this.i = i;
this.j = j;
this.separator = separator;
this.year = year;
this.month = month;
this.day = day;
this.expectedGuesses = expectedGuesses;
}

@Test
public void testDateGuess() throws Exception {
Context context = StandardContext.build();
Match match = MatchFactory.createDateMatch(i, j, token, separator, year, month, day);
String msg = String.format("the date pattern '%s' has guesses of %s", token, expectedGuesses);
assertEquals(msg, expectedGuesses, new DateGuess(context).exec(match), 0.0);
}

@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{"23525", 0, 4, "", 2025, 5, 23, 7300.0},
});
}
}
}
Loading