File: spatialMatch.go

package info (click to toggle)
golang-github-nbutton23-zxcvbn-go 0.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,448 kB
  • sloc: makefile: 6
file content (87 lines) | stat: -rw-r--r-- 2,425 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package matching

import (
	"strings"

	"github.com/nbutton23/zxcvbn-go/adjacency"
	"github.com/nbutton23/zxcvbn-go/entropy"
	"github.com/nbutton23/zxcvbn-go/match"
)

const SPATIAL_MATCHER_NAME = "SPATIAL"

func FilterSpatialMatcher(m match.Matcher) bool {
	return m.ID == SPATIAL_MATCHER_NAME
}

func spatialMatch(password string) (matches []match.Match) {
	for _, graph := range ADJACENCY_GRAPHS {
		if graph.Graph != nil {
			matches = append(matches, spatialMatchHelper(password, graph)...)
		}
	}
	return matches
}

func spatialMatchHelper(password string, graph adjacency.AdjacencyGraph) (matches []match.Match) {

	for i := 0; i < len(password)-1; {
		j := i + 1
		lastDirection := -99 //an int that it should never be!
		turns := 0
		shiftedCount := 0

		for {
			prevChar := password[j-1]
			found := false
			foundDirection := -1
			curDirection := -1
			//My graphs seem to be wrong. . . and where the hell is qwerty
			adjacents := graph.Graph[string(prevChar)]
			//Consider growing pattern by one character if j hasn't gone over the edge
			if j < len(password) {
				curChar := password[j]
				for _, adj := range adjacents {
					curDirection += 1

					if strings.Index(adj, string(curChar)) != -1 {
						found = true
						foundDirection = curDirection

						if strings.Index(adj, string(curChar)) == 1 {
							//index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc.
							//for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted.
							shiftedCount += 1
						}

						if lastDirection != foundDirection {
							//adding a turn is correct even in the initial case when last_direction is null:
							//every spatial pattern starts with a turn.
							turns += 1
							lastDirection = foundDirection
						}
						break
					}
				}
			}

			//if the current pattern continued, extend j and try to grow again
			if found {
				j += 1
			} else {
				//otherwise push the pattern discovered so far, if any...
				//don't consider length 1 or 2 chains.
				if j-i > 2 {
					matchSpc := match.Match{Pattern: "spatial", I: i, J: j - 1, Token: password[i:j], DictionaryName: graph.Name}
					matchSpc.Entropy = entropy.SpatialEntropy(matchSpc, turns, shiftedCount)
					matches = append(matches, matchSpc)
				}
				//. . . and then start a new search from the rest of the password
				i = j
				break
			}
		}

	}
	return matches
}