/// <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); }
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); }