You've already forked postgres_exporter
mirror of
https://github.com/prometheus-community/postgres_exporter.git
synced 2025-08-09 15:42:47 +03:00
Add self-contained gometalinter build tooling.
This commit is contained in:
189
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/dateMatchers.go
generated
vendored
Normal file
189
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/dateMatchers.go
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func checkDate(day, month, year int64) (bool, int64, int64, int64) {
|
||||
if (12 <= month && month <= 31) && day <= 12 {
|
||||
day, month = month, day
|
||||
}
|
||||
|
||||
if day > 31 || month > 12 {
|
||||
return false, 0, 0, 0
|
||||
}
|
||||
|
||||
if !((1900 <= year && year <= 2019) || (0 <= year && year <= 99)) {
|
||||
return false, 0, 0, 0
|
||||
}
|
||||
|
||||
return true, day, month, year
|
||||
}
|
||||
func dateSepMatcher(password string) []match.Match {
|
||||
dateMatches := dateSepMatchHelper(password)
|
||||
|
||||
var matches []match.Match
|
||||
for _, dateMatch := range dateMatches {
|
||||
match := match.Match{
|
||||
I: dateMatch.I,
|
||||
J: dateMatch.J,
|
||||
Entropy: entropy.DateEntropy(dateMatch),
|
||||
DictionaryName: "date_match",
|
||||
Token: dateMatch.Token,
|
||||
}
|
||||
|
||||
matches = append(matches, match)
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
func dateSepMatchHelper(password string) []match.DateMatch {
|
||||
|
||||
var matches []match.DateMatch
|
||||
|
||||
matcher := regexp.MustCompile(DATE_RX_YEAR_SUFFIX)
|
||||
for _, v := range matcher.FindAllString(password, len(password)) {
|
||||
splitV := matcher.FindAllStringSubmatch(v, len(v))
|
||||
i := strings.Index(password, v)
|
||||
j := i + len(v)
|
||||
day, _ := strconv.ParseInt(splitV[0][4], 10, 16)
|
||||
month, _ := strconv.ParseInt(splitV[0][2], 10, 16)
|
||||
year, _ := strconv.ParseInt(splitV[0][6], 10, 16)
|
||||
match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]}
|
||||
matches = append(matches, match)
|
||||
}
|
||||
|
||||
matcher = regexp.MustCompile(DATE_RX_YEAR_PREFIX)
|
||||
for _, v := range matcher.FindAllString(password, len(password)) {
|
||||
splitV := matcher.FindAllStringSubmatch(v, len(v))
|
||||
i := strings.Index(password, v)
|
||||
j := i + len(v)
|
||||
day, _ := strconv.ParseInt(splitV[0][4], 10, 16)
|
||||
month, _ := strconv.ParseInt(splitV[0][6], 10, 16)
|
||||
year, _ := strconv.ParseInt(splitV[0][2], 10, 16)
|
||||
match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]}
|
||||
matches = append(matches, match)
|
||||
}
|
||||
|
||||
var out []match.DateMatch
|
||||
for _, match := range matches {
|
||||
if valid, day, month, year := checkDate(match.Day, match.Month, match.Year); valid {
|
||||
match.Pattern = "date"
|
||||
match.Day = day
|
||||
match.Month = month
|
||||
match.Year = year
|
||||
out = append(out, match)
|
||||
}
|
||||
}
|
||||
return out
|
||||
|
||||
}
|
||||
|
||||
type DateMatchCandidate struct {
|
||||
DayMonth string
|
||||
Year string
|
||||
I, J int
|
||||
}
|
||||
|
||||
type DateMatchCandidateTwo struct {
|
||||
Day string
|
||||
Month string
|
||||
Year string
|
||||
I, J int
|
||||
}
|
||||
|
||||
func dateWithoutSepMatch(password string) []match.Match {
|
||||
dateMatches := dateWithoutSepMatchHelper(password)
|
||||
|
||||
var matches []match.Match
|
||||
for _, dateMatch := range dateMatches {
|
||||
match := match.Match{
|
||||
I: dateMatch.I,
|
||||
J: dateMatch.J,
|
||||
Entropy: entropy.DateEntropy(dateMatch),
|
||||
DictionaryName: "date_match",
|
||||
Token: dateMatch.Token,
|
||||
}
|
||||
|
||||
matches = append(matches, match)
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
//TODO Has issues with 6 digit dates
|
||||
func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) {
|
||||
matcher := regexp.MustCompile(DATE_WITHOUT_SEP_MATCH)
|
||||
for _, v := range matcher.FindAllString(password, len(password)) {
|
||||
i := strings.Index(password, v)
|
||||
j := i + len(v)
|
||||
length := len(v)
|
||||
lastIndex := length - 1
|
||||
var candidatesRoundOne []DateMatchCandidate
|
||||
|
||||
if length <= 6 {
|
||||
//2-digit year prefix
|
||||
candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[2:], v[0:2], i, j))
|
||||
|
||||
//2-digityear suffix
|
||||
candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-2], v[lastIndex-2:], i, j))
|
||||
}
|
||||
if length >= 6 {
|
||||
//4-digit year prefix
|
||||
candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[4:], v[0:4], i, j))
|
||||
|
||||
//4-digit year sufix
|
||||
candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-3], v[lastIndex-3:], i, j))
|
||||
}
|
||||
|
||||
var candidatesRoundTwo []DateMatchCandidateTwo
|
||||
for _, c := range candidatesRoundOne {
|
||||
if len(c.DayMonth) == 2 {
|
||||
candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:1], c.Year, c.I, c.J))
|
||||
} else if len(c.DayMonth) == 3 {
|
||||
candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:2], c.Year, c.I, c.J))
|
||||
candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:3], c.Year, c.I, c.J))
|
||||
} else if len(c.DayMonth) == 4 {
|
||||
candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:4], c.Year, c.I, c.J))
|
||||
}
|
||||
}
|
||||
|
||||
for _, candidate := range candidatesRoundTwo {
|
||||
intDay, err := strconv.ParseInt(candidate.Day, 10, 16)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
intMonth, err := strconv.ParseInt(candidate.Month, 10, 16)
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
intYear, err := strconv.ParseInt(candidate.Year, 10, 16)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if ok, _, _, _ := checkDate(intDay, intMonth, intYear); ok {
|
||||
matches = append(matches, match.DateMatch{Token: password, Pattern: "date", Day: intDay, Month: intMonth, Year: intYear, I: i, J: j})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
func buildDateMatchCandidate(dayMonth, year string, i, j int) DateMatchCandidate {
|
||||
return DateMatchCandidate{DayMonth: dayMonth, Year: year, I: i, J: j}
|
||||
}
|
||||
|
||||
func buildDateMatchCandidateTwo(day, month string, year string, i, j int) DateMatchCandidateTwo {
|
||||
|
||||
return DateMatchCandidateTwo{Day: day, Month: month, Year: year, I: i, J: j}
|
||||
}
|
54
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/dictionaryMatch.go
generated
vendored
Normal file
54
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/dictionaryMatch.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func buildDictMatcher(dictName string, rankedDict map[string]int) func(password string) []match.Match {
|
||||
return func(password string) []match.Match {
|
||||
matches := dictionaryMatch(password, dictName, rankedDict)
|
||||
for _, v := range matches {
|
||||
v.DictionaryName = dictName
|
||||
}
|
||||
return matches
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func buildRankedDict(unrankedList []string) map[string]int {
|
||||
|
||||
result := make(map[string]int)
|
||||
|
||||
for i, v := range unrankedList {
|
||||
result[strings.ToLower(v)] = i + 1
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
68
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/leet.go
generated
vendored
Normal file
68
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/leet.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func l33tMatch(password string) []match.Match {
|
||||
|
||||
substitutions := relevantL33tSubtable(password)
|
||||
|
||||
permutations := getAllPermutationsOfLeetSubstitutions(password, substitutions)
|
||||
|
||||
var matches []match.Match
|
||||
|
||||
for _, permutation := range permutations {
|
||||
for _, mather := range DICTIONARY_MATCHERS {
|
||||
matches = append(matches, mather(permutation)...)
|
||||
}
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
match.Entropy += entropy.ExtraLeetEntropy(match, password)
|
||||
match.DictionaryName = match.DictionaryName + "_3117"
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
func getAllPermutationsOfLeetSubstitutions(password string, substitutionsMap map[string][]string) []string {
|
||||
|
||||
var permutations []string
|
||||
|
||||
for index, char := range password {
|
||||
for value, splice := range substitutionsMap {
|
||||
for _, sub := range splice {
|
||||
if string(char) == sub {
|
||||
var permutation string
|
||||
permutation = password[:index] + value + password[index+1:]
|
||||
|
||||
permutations = append(permutations, permutation)
|
||||
if index < len(permutation) {
|
||||
tempPermutations := getAllPermutationsOfLeetSubstitutions(permutation[index+1:], substitutionsMap)
|
||||
for _, temp := range tempPermutations {
|
||||
permutations = append(permutations, permutation[:index+1]+temp)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return permutations
|
||||
}
|
||||
|
||||
func relevantL33tSubtable(password string) map[string][]string {
|
||||
relevantSubs := make(map[string][]string)
|
||||
for key, values := range L33T_TABLE.Graph {
|
||||
for _, value := range values {
|
||||
if strings.Contains(password, value) {
|
||||
relevantSubs[key] = append(relevantSubs[key], value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return relevantSubs
|
||||
}
|
77
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/matching.go
generated
vendored
Normal file
77
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/matching.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/adjacency"
|
||||
"github.com/nbutton23/zxcvbn-go/frequency"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"sort"
|
||||
)
|
||||
|
||||
var (
|
||||
DICTIONARY_MATCHERS []func(password string) []match.Match
|
||||
MATCHERS []func(password string) []match.Match
|
||||
ADJACENCY_GRAPHS []adjacency.AdjacencyGraph
|
||||
L33T_TABLE adjacency.AdjacencyGraph
|
||||
|
||||
SEQUENCES map[string]string
|
||||
)
|
||||
|
||||
const (
|
||||
DATE_RX_YEAR_SUFFIX string = `((\d{1,2})(\s|-|\/|\\|_|\.)(\d{1,2})(\s|-|\/|\\|_|\.)(19\d{2}|200\d|201\d|\d{2}))`
|
||||
DATE_RX_YEAR_PREFIX string = `((19\d{2}|200\d|201\d|\d{2})(\s|-|/|\\|_|\.)(\d{1,2})(\s|-|/|\\|_|\.)(\d{1,2}))`
|
||||
DATE_WITHOUT_SEP_MATCH string = `\d{4,8}`
|
||||
)
|
||||
|
||||
func init() {
|
||||
loadFrequencyList()
|
||||
}
|
||||
|
||||
func Omnimatch(password string, userInputs []string) (matches []match.Match) {
|
||||
|
||||
//Can I run into the issue where nil is not equal to nil?
|
||||
if DICTIONARY_MATCHERS == nil || ADJACENCY_GRAPHS == nil {
|
||||
loadFrequencyList()
|
||||
}
|
||||
|
||||
if userInputs != nil {
|
||||
userInputMatcher := buildDictMatcher("user_inputs", buildRankedDict(userInputs))
|
||||
matches = userInputMatcher(password)
|
||||
}
|
||||
|
||||
for _, matcher := range MATCHERS {
|
||||
matches = append(matches, matcher(password)...)
|
||||
}
|
||||
sort.Sort(match.Matches(matches))
|
||||
return matches
|
||||
}
|
||||
|
||||
func loadFrequencyList() {
|
||||
|
||||
for n, list := range frequency.FrequencyLists {
|
||||
DICTIONARY_MATCHERS = append(DICTIONARY_MATCHERS, buildDictMatcher(n, buildRankedDict(list.List)))
|
||||
}
|
||||
|
||||
L33T_TABLE = adjacency.AdjacencyGph["l33t"]
|
||||
|
||||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, adjacency.AdjacencyGph["qwerty"])
|
||||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, adjacency.AdjacencyGph["dvorak"])
|
||||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, adjacency.AdjacencyGph["keypad"])
|
||||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, adjacency.AdjacencyGph["macKeypad"])
|
||||
|
||||
//l33tFilePath, _ := filepath.Abs("adjacency/L33t.json")
|
||||
//L33T_TABLE = adjacency.GetAdjancencyGraphFromFile(l33tFilePath, "l33t")
|
||||
|
||||
SEQUENCES = make(map[string]string)
|
||||
SEQUENCES["lower"] = "abcdefghijklmnopqrstuvwxyz"
|
||||
SEQUENCES["upper"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
SEQUENCES["digits"] = "0123456789"
|
||||
|
||||
MATCHERS = append(MATCHERS, DICTIONARY_MATCHERS...)
|
||||
MATCHERS = append(MATCHERS, spatialMatch)
|
||||
MATCHERS = append(MATCHERS, repeatMatch)
|
||||
MATCHERS = append(MATCHERS, sequenceMatch)
|
||||
MATCHERS = append(MATCHERS, l33tMatch)
|
||||
MATCHERS = append(MATCHERS, dateSepMatcher)
|
||||
MATCHERS = append(MATCHERS, dateWithoutSepMatch)
|
||||
|
||||
}
|
59
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/repeatMatch.go
generated
vendored
Normal file
59
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/repeatMatch.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
68
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/sequenceMatch.go
generated
vendored
Normal file
68
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/sequenceMatch.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
80
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/spatialMatch.go
generated
vendored
Normal file
80
tools/vendor/github.com/nbutton23/zxcvbn-go/matching/spatialMatch.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/adjacency"
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user