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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        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);
        }
Exemple #6
0
        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);
        }