commit
aa63dc8ac7
|
@ -33,3 +33,8 @@ type DateMatch struct {
|
|||
Separator string
|
||||
Day, Month, Year int64
|
||||
}
|
||||
|
||||
type Matcher struct {
|
||||
MatchingFunc func(password string) []Match
|
||||
ID string
|
||||
}
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
)
|
||||
|
||||
const (
|
||||
DATESEP_MATCHER_NAME = "DATESEP"
|
||||
DATEWITHOUTSEP_MATCHER_NAME = "DATEWITHOUT"
|
||||
)
|
||||
|
||||
func FilterDateSepMatcher(m match.Matcher) bool {
|
||||
return m.ID == DATESEP_MATCHER_NAME
|
||||
}
|
||||
|
||||
func FilterDateWithoutSepMatcher(m match.Matcher) bool {
|
||||
return m.ID == DATEWITHOUTSEP_MATCHER_NAME
|
||||
}
|
||||
|
||||
func checkDate(day, month, year int64) (bool, int64, int64, int64) {
|
||||
if (12 <= month && month <= 31) && day <= 12 {
|
||||
day, month = month, day
|
||||
|
@ -23,6 +37,7 @@ func checkDate(day, month, year int64) (bool, int64, int64, int64) {
|
|||
|
||||
return true, day, month, year
|
||||
}
|
||||
|
||||
func dateSepMatcher(password string) []match.Match {
|
||||
dateMatches := dateSepMatchHelper(password)
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const L33T_MATCHER_NAME = "l33t"
|
||||
|
||||
func FilterL33tMatcher(m match.Matcher) bool {
|
||||
return m.ID == L33T_MATCHER_NAME
|
||||
}
|
||||
|
||||
func l33tMatch(password string) []match.Match {
|
||||
|
||||
substitutions := relevantL33tSubtable(password)
|
||||
|
@ -16,7 +23,7 @@ func l33tMatch(password string) []match.Match {
|
|||
|
||||
for _, permutation := range permutations {
|
||||
for _, mather := range DICTIONARY_MATCHERS {
|
||||
matches = append(matches, mather(permutation)...)
|
||||
matches = append(matches, mather.MatchingFunc(permutation)...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"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
|
||||
DICTIONARY_MATCHERS []match.Matcher
|
||||
MATCHERS []match.Matcher
|
||||
ADJACENCY_GRAPHS []adjacency.AdjacencyGraph
|
||||
L33T_TABLE adjacency.AdjacencyGraph
|
||||
|
||||
|
@ -26,7 +27,7 @@ func init() {
|
|||
loadFrequencyList()
|
||||
}
|
||||
|
||||
func Omnimatch(password string, userInputs []string) (matches []match.Match) {
|
||||
func Omnimatch(password string, userInputs []string, filters ...func(match.Matcher) bool) (matches []match.Match) {
|
||||
|
||||
//Can I run into the issue where nil is not equal to nil?
|
||||
if DICTIONARY_MATCHERS == nil || ADJACENCY_GRAPHS == nil {
|
||||
|
@ -39,7 +40,16 @@ func Omnimatch(password string, userInputs []string) (matches []match.Match) {
|
|||
}
|
||||
|
||||
for _, matcher := range MATCHERS {
|
||||
matches = append(matches, matcher(password)...)
|
||||
shouldBeFiltered := false
|
||||
for i := range filters {
|
||||
if filters[i](matcher) {
|
||||
shouldBeFiltered = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !shouldBeFiltered {
|
||||
matches = append(matches, matcher.MatchingFunc(password)...)
|
||||
}
|
||||
}
|
||||
sort.Sort(match.Matches(matches))
|
||||
return matches
|
||||
|
@ -48,7 +58,7 @@ func Omnimatch(password string, userInputs []string) (matches []match.Match) {
|
|||
func loadFrequencyList() {
|
||||
|
||||
for n, list := range frequency.FrequencyLists {
|
||||
DICTIONARY_MATCHERS = append(DICTIONARY_MATCHERS, buildDictMatcher(n, buildRankedDict(list.List)))
|
||||
DICTIONARY_MATCHERS = append(DICTIONARY_MATCHERS, match.Matcher{MatchingFunc: buildDictMatcher(n, buildRankedDict(list.List)), ID: n})
|
||||
}
|
||||
|
||||
L33T_TABLE = adjacency.AdjacencyGph["l33t"]
|
||||
|
@ -67,11 +77,11 @@ func loadFrequencyList() {
|
|||
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)
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: spatialMatch, ID: SPATIAL_MATCHER_NAME})
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: repeatMatch, ID: REPEAT_MATCHER_NAME})
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: sequenceMatch, ID: SEQUENCE_MATCHER_NAME})
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: l33tMatch, ID: L33T_MATCHER_NAME})
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: dateSepMatcher, ID: DATESEP_MATCHER_NAME})
|
||||
MATCHERS = append(MATCHERS, match.Matcher{MatchingFunc: dateWithoutSepMatch, ID: DATEWITHOUTSEP_MATCHER_NAME})
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const REPEAT_MATCHER_NAME = "REPEAT"
|
||||
|
||||
func FilterRepeatMatcher(m match.Matcher) bool {
|
||||
return m.ID == REPEAT_MATCHER_NAME
|
||||
}
|
||||
|
||||
func repeatMatch(password string) []match.Match {
|
||||
var matches []match.Match
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const SEQUENCE_MATCHER_NAME = "SEQ"
|
||||
|
||||
func FilterSequenceMatcher(m match.Matcher) bool {
|
||||
return m.ID == SEQUENCE_MATCHER_NAME
|
||||
}
|
||||
|
||||
func sequenceMatch(password string) []match.Match {
|
||||
var matches []match.Match
|
||||
for i := 0; i < len(password); {
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package matching
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/adjacency"
|
||||
"github.com/nbutton23/zxcvbn-go/entropy"
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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 {
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
package zxcvbn
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/nbutton23/zxcvbn-go/match"
|
||||
"github.com/nbutton23/zxcvbn-go/matching"
|
||||
"github.com/nbutton23/zxcvbn-go/scoring"
|
||||
"github.com/nbutton23/zxcvbn-go/utils/math"
|
||||
"time"
|
||||
)
|
||||
|
||||
func PasswordStrength(password string, userInputs []string) scoring.MinEntropyMatch {
|
||||
func PasswordStrength(password string, userInputs []string, filters ...func(match.Matcher) bool) scoring.MinEntropyMatch {
|
||||
start := time.Now()
|
||||
matches := matching.Omnimatch(password, userInputs)
|
||||
matches := matching.Omnimatch(password, userInputs, filters...)
|
||||
result := scoring.MinimumEntropyMatchSequence(password, matches)
|
||||
end := time.Now()
|
||||
|
||||
|
|
Loading…
Reference in New Issue