示例#1
0
        public void AccountsForTurnPositionsDirectionsAndStartingKey()
        {
            var match = new SpatialMatch
            {
                Token        = "zxcvbn",
                Graph        = "qwerty",
                Turns        = 3,
                ShiftedCount = 0,
                i            = 1,
                j            = 2,
            };

            var l        = match.Token.Length;
            var s        = SpatialGuessesCalculator.KeyboardStartingPositions;
            var d        = SpatialGuessesCalculator.KeyboardAverageDegree;
            var expected = 0.0;

            for (var i = 2; i <= l; i++)
            {
                for (var j = 1; j <= Math.Min(match.Turns, i - 1); j++)
                {
                    expected += PasswordScoring.Binomial(i - 1, j - 1) * s * Math.Pow(d, j);
                }
            }

            var actual = SpatialGuessesCalculator.CalculateGuesses(match);

            actual.Should().Be(expected);
        }
示例#2
0
        private void GetMatchFeedback(Match match, bool isSoleMatch, PasswordMetricResult result)
        {
            switch (match.Pattern)
            {
            case "dictionary":
                GetDictionaryMatchFeedback((DictionaryMatch)match, isSoleMatch, result);
                break;

            case "spatial":
                SpatialMatch spatialMatch = (SpatialMatch)match;

                if (spatialMatch.Turns == 1)
                {
                    result.warning = Warning.StraightRow;
                }
                else
                {
                    result.warning = Warning.ShortKeyboardPatterns;
                }

                result.suggestions.Clear();
                result.suggestions.Add(Suggestion.UseLongerKeyboardPattern);
                break;

            case "repeat":
                //todo: add support for repeated sequences longer than 1 char
                //  if(match.Token.Length == 1)
                result.warning = Warning.RepeatsLikeAaaEasy;
                //  else
                //       result.warning = Warning.RepeatsLikeAbcSlighterHarder;

                result.suggestions.Clear();
                result.suggestions.Add(Suggestion.AvoidRepeatedWordsAndChars);
                break;

            case "sequence":
                result.warning = Warning.SequenceAbcEasy;

                result.suggestions.Clear();
                result.suggestions.Add(Suggestion.AvoidSequences);
                break;

            //todo: add support for recent_year, however not example exist on https://dl.dropboxusercontent.com/u/209/zxcvbn/test/index.html


            case "date":
                result.warning = Warning.DatesEasy;

                result.suggestions.Clear();
                result.suggestions.Add(Suggestion.AvoidDatesYearsAssociatedYou);
                break;
            }
        }
示例#3
0
        /// <summary>
        /// Estimates the attempts required to guess the password.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <returns>The guesses estimate.</returns>
        public static double CalculateGuesses(SpatialMatch match)
        {
            int    s;
            double d;

            if (match.Graph == "qwerty" || match.Graph == "dvorak")
            {
                s = KeyboardStartingPositions;
                d = KeyboardAverageDegree;
            }
            else
            {
                s = KeypadStartingPositions;
                d = KeypadAverageDegree;
            }

            double guesses = 0;
            var    l       = match.Token.Length;
            var    t       = match.Turns;

            for (var i = 2; i <= l; i++)
            {
                var possibleTurns = Math.Min(t, i - 1);
                for (var j = 1; j <= possibleTurns; j++)
                {
                    guesses += PasswordScoring.Binomial(i - 1, j - 1) * s * Math.Pow(d, j);
                }
            }

            if (match.ShiftedCount > 0)
            {
                var shifted   = match.ShiftedCount;
                var unshifted = match.Token.Length - match.ShiftedCount;
                if (shifted == 0 || unshifted == 0)
                {
                    guesses *= 2;
                }
                else
                {
                    double variations = 0;
                    for (var i = 1; i <= Math.Min(shifted, unshifted); i++)
                    {
                        variations += PasswordScoring.Binomial(shifted + unshifted, i);
                    }

                    guesses *= variations;
                }
            }

            return(guesses);
        }
示例#4
0
        private static double SpatialGuesses(Match match)
        {
            SpatialMatch sm = (SpatialMatch)match;
            double       s;
            double       d;

            if (sm.Graph.Equals("qwerty") || sm.Graph.Equals("dvorak"))
            {
                s = 4.596;
                d = 94;
            }
            else
            {
                s = 5.0;
                d = 15.5;
            }
            double guesses = 0;
            int    L       = sm.Token.Length;
            int    t       = sm.Turns;

            foreach (int i in EnumerableUtility.Range(2, L + 1))
            {
                int possible_turns = (int)Math.Min(t, i - 1);
                foreach (int j in EnumerableUtility.Range(1, possible_turns + 1))
                {
                    guesses += nCk(i - 1, j - 1) * s * Math.Pow(d, j);
                }
            }
            if (sm.ShiftedCount > 0)
            {
                int S = sm.ShiftedCount;
                int U = sm.Token.Length - S;
                if (S == 0 || U == 0)
                {
                    guesses *= 2;
                }
                else
                {
                    double shiftedVariations = 0;
                    int    rangeEnd          = (int)Math.Min(S, U);
                    foreach (int i in EnumerableUtility.Range(1, rangeEnd + 1))
                    {
                        shiftedVariations += nCk(S + U, i);
                    }
                    guesses *= shiftedVariations;
                }
            }

            return(guesses);
        }
示例#5
0
        public void GuessesWhenThereAreNoTurns()
        {
            var match = new SpatialMatch
            {
                Token        = "zxcvbn",
                Graph        = "qwerty",
                Turns        = 1,
                ShiftedCount = 0,
                i            = 1,
                j            = 2,
            };

            var expected = SpatialGuessesCalculator.KeyboardStartingPositions * SpatialGuessesCalculator.KeyboardAverageDegree * (match.Token.Length - 1);

            var actual = SpatialGuessesCalculator.CalculateGuesses(match);

            actual.Should().Be(expected);
        }
示例#6
0
        public void DoublesGuessesIfEverythingIsShifted()
        {
            var match = new SpatialMatch
            {
                Token        = "zxcvbn",
                Graph        = "qwerty",
                Turns        = 1,
                ShiftedCount = 6,
                i            = 1,
                j            = 2,
            };

            var expected = SpatialGuessesCalculator.KeyboardStartingPositions * SpatialGuessesCalculator.KeyboardAverageDegree * (match.Token.Length - 1) * 2;

            var actual = SpatialGuessesCalculator.CalculateGuesses(match);

            actual.Should().Be(expected);
        }
示例#7
0
        public void IsDelegatedToByEstimateGuesses()
        {
            var match = new SpatialMatch
            {
                Token        = "zxcvbn",
                Graph        = "qwerty",
                Turns        = 1,
                ShiftedCount = 0,
                i            = 1,
                j            = 2,
            };

            var expected = SpatialGuessesCalculator.KeyboardStartingPositions * SpatialGuessesCalculator.KeyboardAverageDegree * (match.Token.Length - 1);

            var actual = PasswordScoring.EstimateGuesses(match, match.Token);

            actual.Should().Be(expected);
        }