gitee.com/lonely0422/gometalinter.git@v3.0.1-0.20190307123442-32416ab75314+incompatible/_linters/src/github.com/nbutton23/zxcvbn-go/matching/spatialMatch.go (about)

     1  package matching
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/nbutton23/zxcvbn-go/adjacency"
     7  	"github.com/nbutton23/zxcvbn-go/entropy"
     8  	"github.com/nbutton23/zxcvbn-go/match"
     9  )
    10  
    11  const SPATIAL_MATCHER_NAME = "SPATIAL"
    12  
    13  func FilterSpatialMatcher(m match.Matcher) bool {
    14  	return m.ID == SPATIAL_MATCHER_NAME
    15  }
    16  
    17  func spatialMatch(password string) (matches []match.Match) {
    18  	for _, graph := range ADJACENCY_GRAPHS {
    19  		if graph.Graph != nil {
    20  			matches = append(matches, spatialMatchHelper(password, graph)...)
    21  		}
    22  	}
    23  	return matches
    24  }
    25  
    26  func spatialMatchHelper(password string, graph adjacency.AdjacencyGraph) (matches []match.Match) {
    27  
    28  	for i := 0; i < len(password)-1; {
    29  		j := i + 1
    30  		lastDirection := -99 //an int that it should never be!
    31  		turns := 0
    32  		shiftedCount := 0
    33  
    34  		for {
    35  			prevChar := password[j-1]
    36  			found := false
    37  			foundDirection := -1
    38  			curDirection := -1
    39  			//My graphs seem to be wrong. . . and where the hell is qwerty
    40  			adjacents := graph.Graph[string(prevChar)]
    41  			//Consider growing pattern by one character if j hasn't gone over the edge
    42  			if j < len(password) {
    43  				curChar := password[j]
    44  				for _, adj := range adjacents {
    45  					curDirection += 1
    46  
    47  					if strings.Index(adj, string(curChar)) != -1 {
    48  						found = true
    49  						foundDirection = curDirection
    50  
    51  						if strings.Index(adj, string(curChar)) == 1 {
    52  							//index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc.
    53  							//for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted.
    54  							shiftedCount += 1
    55  						}
    56  
    57  						if lastDirection != foundDirection {
    58  							//adding a turn is correct even in the initial case when last_direction is null:
    59  							//every spatial pattern starts with a turn.
    60  							turns += 1
    61  							lastDirection = foundDirection
    62  						}
    63  						break
    64  					}
    65  				}
    66  			}
    67  
    68  			//if the current pattern continued, extend j and try to grow again
    69  			if found {
    70  				j += 1
    71  			} else {
    72  				//otherwise push the pattern discovered so far, if any...
    73  				//don't consider length 1 or 2 chains.
    74  				if j-i > 2 {
    75  					matchSpc := match.Match{Pattern: "spatial", I: i, J: j - 1, Token: password[i:j], DictionaryName: graph.Name}
    76  					matchSpc.Entropy = entropy.SpatialEntropy(matchSpc, turns, shiftedCount)
    77  					matches = append(matches, matchSpc)
    78  				}
    79  				//. . . and then start a new search from the rest of the password
    80  				i = j
    81  				break
    82  			}
    83  		}
    84  
    85  	}
    86  	return matches
    87  }