public void MostGuessableMatchSequenceReturnsBruteForceThenMatchThenBruteForceWhenMatchCoversAnInfixOfPassword() { var password = "******"; var existingMatch = CreateTestMatch(1, 8, 1); var expected = new List <Match> { new BruteForceMatch { i = 0, j = 0, Token = "0", Guesses = 11, }, existingMatch, new BruteForceMatch { i = 9, j = 9, Token = "9", Guesses = 11, }, }; var result = PasswordScoring.MostGuessableMatchSequence(password, new List <Match> { existingMatch }, true); result.Sequence.Should().BeEquivalentTo(expected); }
public void MostGuessableMatchSequenceChoosesOptimalMatches() { var password = "******"; var m0 = CreateTestMatch(0, 9, 3); var m1 = CreateTestMatch(0, 3, 2); var m2 = CreateTestMatch(4, 9, 1); var expected = new List <Match> { m0, }; var result = PasswordScoring.MostGuessableMatchSequence(password, new List <Match> { m0, m1, m2 }, true); result.Sequence.Should().BeEquivalentTo(expected); m0.Guesses = 5; expected = new List <Match> { m1, m2, }; result = PasswordScoring.MostGuessableMatchSequence(password, new List <Match> { m0, m1, m2 }, true); result.Sequence.Should().BeEquivalentTo(expected); }
/// <summary> /// Find repeat matches in <paramref name="password" />. /// </summary> /// <param name="password">The password to check.</param> /// <returns>An enumerable of repeat matches.</returns> public IEnumerable <Matches.Match> MatchPassword(string password) { var matches = new List <Matches.Match>(); var greedy = "(.+)\\1+"; var lazy = "(.+?)\\1+"; var lazyAnchored = "^(.+?)\\1+$"; var lastIndex = 0; while (lastIndex < password.Length) { var greedyMatch = Regex.Match(password.Substring(lastIndex), greedy); var lazyMatch = Regex.Match(password.Substring(lastIndex), lazy); if (!greedyMatch.Success) { break; } System.Text.RegularExpressions.Match match; string baseToken; if (greedyMatch.Length > lazyMatch.Length) { match = greedyMatch; baseToken = Regex.Match(match.Value, lazyAnchored).Groups[1].Value; } else { match = lazyMatch; baseToken = match.Groups[1].Value; } var i = lastIndex + match.Index; var j = lastIndex + match.Index + match.Length - 1; var baseAnalysis = PasswordScoring.MostGuessableMatchSequence(baseToken, Core.GetAllMatches(baseToken)); var baseMatches = baseAnalysis.Sequence; var baseGuesses = baseAnalysis.Guesses; var m = new RepeatMatch { i = i, j = j, Token = match.Value, BaseToken = baseToken, BaseGuesses = baseGuesses, RepeatCount = match.Length / baseToken.Length, }; m.BaseMatchItems.AddRange(baseMatches); matches.Add(m); lastIndex = j + 1; } return(matches); }
public void IsDelegatedToByEstimateGuesses() { var match = new RepeatMatch { Token = "aa", BaseToken = "a", BaseGuesses = PasswordScoring.MostGuessableMatchSequence("a", Core.GetAllMatches("a")).Guesses, BaseMatchItems = new List <Match>(), RepeatCount = 2, i = 1, j = 2, }; var expected = RepeatGuessesCalculator.CalculateGuesses(match); var actual = PasswordScoring.EstimateGuesses(match, "aa"); actual.Should().Be(expected); }
public void MostGuessableMatchSequenceRetursnOneMatchForEmptySequence() { var password = "******"; var expected = new List <Match> { new BruteForceMatch { i = 0, j = 9, Token = password, Guesses = 10000000000, }, }; var result = PasswordScoring.MostGuessableMatchSequence(password, Enumerable.Empty <Match>()); result.Sequence.Should().BeEquivalentTo(expected); }
public void CalculatesTheRightNumberOfGuesses(string token, string baseToken, int expectedRepeats) { var baseGuesses = PasswordScoring.MostGuessableMatchSequence(baseToken, Core.GetAllMatches(baseToken)).Guesses; var match = new RepeatMatch { Token = token, BaseToken = baseToken, BaseGuesses = baseGuesses, RepeatCount = expectedRepeats, BaseMatchItems = new List <Match>(), i = 1, j = 2, }; var expected = baseGuesses * expectedRepeats; var actual = RepeatGuessesCalculator.CalculateGuesses(match); actual.Should().Be(expected); }
public void MostGuessableMatchSequenceChoosesMatchWithFewestGuessesIfTheyMatchTheSameSpan() { var password = "******"; var worseMatch = CreateTestMatch(0, 9, 1); var bestMatch = CreateTestMatch(0, 9, 2); var expected = new List <Match> { worseMatch, }; var result = PasswordScoring.MostGuessableMatchSequence(password, new List <Match> { worseMatch, bestMatch }, true); result.Sequence.Should().BeEquivalentTo(expected); result = PasswordScoring.MostGuessableMatchSequence(password, new List <Match> { bestMatch, worseMatch }, true); result.Sequence.Should().BeEquivalentTo(expected); }