예제 #1
0
func sequenceMatch(password string) []match.Match {
	var matches []match.Match
	for i := 0; i < len(password); {
		j := i + 1
		var seq string
		var seqName string
		seqDirection := 0
		for seqCandidateName, seqCandidate := range SEQUENCES {
			iN := strings.Index(seqCandidate, string(password[i]))
			var jN int
			if j < len(password) {
				jN = strings.Index(seqCandidate, string(password[j]))
			} else {
				jN = -1
			}

			if iN > -1 && jN > -1 {
				direction := jN - iN
				if direction == 1 || direction == -1 {
					seq = seqCandidate
					seqName = seqCandidateName
					seqDirection = direction
					break
				}
			}

		}

		if seq != "" {
			for {
				var prevN, curN int
				if j < len(password) {
					prevChar, curChar := password[j-1], password[j]
					prevN, curN = strings.Index(seq, string(prevChar)), strings.Index(seq, string(curChar))
				}

				if j == len(password) || curN-prevN != seqDirection {
					if j-i > 2 {
						matchSequence := match.Match{
							Pattern:        "sequence",
							I:              i,
							J:              j - 1,
							Token:          password[i:j],
							DictionaryName: seqName,
						}

						matchSequence.Entropy = entropy.SequenceEntropy(matchSequence, len(seq), (seqDirection == 1))
						matches = append(matches, matchSequence)
					}
					break
				} else {
					j += 1
				}

			}
		}
		i = j
	}
	return matches
}
예제 #2
0
func repeatMatch(password string) []match.Match {
	var matches []match.Match

	//Loop through password. if current == prev currentStreak++ else if currentStreak > 2 {buildMatch; currentStreak = 1} prev = current
	var current, prev string
	currentStreak := 1
	var i int
	var char rune
	for i, char = range password {
		current = string(char)
		if i == 0 {
			prev = current
			continue
		}

		if strings.ToLower(current) == strings.ToLower(prev) {
			currentStreak++

		} else if currentStreak > 2 {
			iPos := i - currentStreak
			jPos := i - 1
			matchRepeat := match.Match{
				Pattern:        "repeat",
				I:              iPos,
				J:              jPos,
				Token:          password[iPos : jPos+1],
				DictionaryName: prev}
			matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat)
			matches = append(matches, matchRepeat)
			currentStreak = 1
		} else {
			currentStreak = 1
		}

		prev = current
	}

	if currentStreak > 2 {
		iPos := i - currentStreak + 1
		jPos := i
		matchRepeat := match.Match{
			Pattern:        "repeat",
			I:              iPos,
			J:              jPos,
			Token:          password[iPos : jPos+1],
			DictionaryName: prev}
		matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat)
		matches = append(matches, matchRepeat)
	}
	return matches
}
예제 #3
0
func dictionaryMatch(password string, dictionaryName string, rankedDict map[string]int) []match.Match {
	length := len(password)
	var results []match.Match
	pwLower := strings.ToLower(password)

	for i := 0; i < length; i++ {
		for j := i; j < length; j++ {
			word := pwLower[i : j+1]
			if val, ok := rankedDict[word]; ok {
				matchDic := match.Match{Pattern: "dictionary",
					DictionaryName: dictionaryName,
					I:              i,
					J:              j,
					Token:          password[i : j+1],
				}
				matchDic.Entropy = entropy.DictionaryEntropy(matchDic, float64(val))

				results = append(results, matchDic)
			}
		}
	}

	return results
}
예제 #4
0
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
}