/// <summary>
        /// Match the password against a single pattern
        /// </summary>
        /// <param name="graph">Adjacency graph for this key layout</param>
        /// <param name="password">Password to match</param>
        /// <returns>List of matching patterns</returns>
        private List <Match> SpatialMatch(SpatialGraph graph, string password)
        {
            var matches = new List <Match>();

            var i = 0;

            while (i < password.Length - 1)
            {
                int turns = 0, shiftedCount = 0;
                var lastDirection = -1;

                var j = i + 1;
                for (; j < password.Length; ++j)
                {
                    bool shifted;
                    var  foundDirection = graph.GetAdjacentCharDirection(password[j - 1], password[j], out shifted);

                    if (foundDirection != -1)
                    {
                        // Spatial match continues
                        if (shifted)
                        {
                            shiftedCount++;
                        }
                        if (lastDirection != foundDirection)
                        {
                            turns++;
                            lastDirection = foundDirection;
                        }
                    }
                    else
                    {
                        break;  // This character not a spatial match
                    }
                }

                // Only consider runs of greater than two
                if (j - i > 2)
                {
                    matches.Add(new SpatialMatch()
                    {
                        Pattern      = SpatialPattern,
                        Begin        = i,
                        End          = j - 1,
                        Token        = password.Substring(i, j - i),
                        Graph        = graph.Name,
                        Entropy      = graph.CalculateEntropy(j - i, turns, shiftedCount),
                        Turns        = turns,
                        ShiftedCount = shiftedCount
                    });
                }

                i = j;
            }

            return(matches);
        }
예제 #2
0
        private static IEnumerable <Matches.Match> SpatialMatch(SpatialGraph graph, string password)
        {
            var matches = new List <Matches.Match>();

            var i = 0;

            while (i < password.Length - 1)
            {
                var turns         = 0;
                var shiftedCount  = 0;
                int?lastDirection = null;

                var j = i + 1;

                if ((graph.Name == "qwerty" || graph.Name == "dvorak") && Regex.IsMatch(password[i].ToString(), ShiftedRegex))
                {
                    shiftedCount = 1;
                }

                while (true)
                {
                    var prevChar         = password[j - 1];
                    var found            = false;
                    var currentDirection = -1;
                    var adjacents        = graph.AdjacencyGraph.ContainsKey(prevChar) ? graph.AdjacencyGraph[prevChar] : Enumerable.Empty <string>();

                    if (j < password.Length)
                    {
                        var curChar = password[j].ToString();
                        foreach (var adjacent in adjacents)
                        {
                            currentDirection++;

                            if (adjacent == null)
                            {
                                continue;
                            }

                            if (adjacent.Contains(curChar))
                            {
                                found = true;
                                var foundDirection = currentDirection;
                                if (adjacent.IndexOf(curChar, StringComparison.Ordinal) == 1)
                                {
                                    shiftedCount++;
                                }

                                if (lastDirection != foundDirection)
                                {
                                    turns++;
                                    lastDirection = foundDirection;
                                }

                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        j++;
                    }
                    else
                    {
                        if (j - i > 2)
                        {
                            matches.Add(new SpatialMatch()
                            {
                                i            = i,
                                j            = j - 1,
                                Token        = password.Substring(i, j - i),
                                Graph        = graph.Name,
                                Turns        = turns,
                                ShiftedCount = shiftedCount,
                            });
                        }

                        i = j;
                        break;
                    }
                }
            }

            return(matches);
        }