Merge pull request #1 from nbutton23/button-repeating-match
Button repeating match
This commit is contained in:
commit
9acbd57b69
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"graph": {
|
||||
"a": [
|
||||
"4",
|
||||
"@"
|
||||
],
|
||||
"b": [
|
||||
"8"
|
||||
],
|
||||
"c": [
|
||||
"(",
|
||||
"{",
|
||||
"[",
|
||||
"<"
|
||||
],
|
||||
"e": [
|
||||
"3"
|
||||
],
|
||||
"g": [
|
||||
"6",
|
||||
"9"
|
||||
],
|
||||
"i": [
|
||||
"1",
|
||||
"!",
|
||||
"|"
|
||||
],
|
||||
"l": [
|
||||
"1",
|
||||
"|",
|
||||
"7"
|
||||
],
|
||||
"o": [
|
||||
"0"
|
||||
],
|
||||
"s": [
|
||||
"$",
|
||||
"5"
|
||||
],
|
||||
"t": [
|
||||
"+",
|
||||
"7"
|
||||
],
|
||||
"x": [
|
||||
"%"
|
||||
],
|
||||
"z": [
|
||||
"2"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
|
||||
type AdjacencyGraph struct {
|
||||
Graph map[string][6]string
|
||||
Graph map[string][]string
|
||||
averageDegree float64
|
||||
Name string
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ type Match struct {
|
|||
Turns int
|
||||
ShiftedCount int
|
||||
Entropy float64
|
||||
RepeatedChar string
|
||||
}
|
||||
|
||||
type DateMatch struct {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"zxcvbn-go/adjacency"
|
||||
"zxcvbn-go/match"
|
||||
"sort"
|
||||
// "github.com/deckarep/golang-set"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -18,6 +19,7 @@ var (
|
|||
KEYBOARD_AVG_DEGREE float64
|
||||
KEYPAD_STARTING_POSITIONS int
|
||||
KEYPAD_AVG_DEGREE float64
|
||||
L33T_TABLE adjacency.AdjacencyGraph
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -82,8 +84,13 @@ func loadFrequencyList() {
|
|||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, keypadGraph)
|
||||
ADJACENCY_GRAPHS = append(ADJACENCY_GRAPHS, adjacency.GetAdjancencyGraphFromFile(macKeypadfilePath, "macKepad"))
|
||||
|
||||
l33tFilePath, _ := filepath.Abs("adjacency/L33t.json")
|
||||
L33T_TABLE = adjacency.GetAdjancencyGraphFromFile(l33tFilePath, "l33t")
|
||||
|
||||
MATCHERS = append(MATCHERS, DICTIONARY_MATCHERS...)
|
||||
MATCHERS = append(MATCHERS, SpatialMatch)
|
||||
MATCHERS = append(MATCHERS, spatialMatch)
|
||||
MATCHERS = append(MATCHERS, repeatMatch)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -246,7 +253,7 @@ func buildDateMatchCandidateTwo(day, month byte, year string, i, j int) match.Da
|
|||
}
|
||||
|
||||
|
||||
func SpatialMatch(password string) (matches []match.Match) {
|
||||
func spatialMatch(password string) (matches []match.Match) {
|
||||
for _, graph := range ADJACENCY_GRAPHS {
|
||||
matches = append(matches, spatialMatchHelper(password, graph)...)
|
||||
}
|
||||
|
@ -299,7 +306,6 @@ func spatialMatchHelper(password string, graph adjacency.AdjacencyGraph) (matche
|
|||
j += 1
|
||||
} else {
|
||||
// otherwise push the pattern discovered so far, if any...
|
||||
|
||||
// don't consider length 1 or 2 chains.
|
||||
if j - i > 2 {
|
||||
matches = append(matches, match.Match{Pattern:"spatial", I:i, J:j - 1, Token:password[i:j], DictionaryName:graph.Name, Turns:turns, ShiftedCount:shiftedCount })
|
||||
|
@ -313,3 +319,80 @@ func spatialMatchHelper(password string, graph adjacency.AdjacencyGraph) (matche
|
|||
}
|
||||
return matches
|
||||
}
|
||||
|
||||
func relevantL33tSubtable(password string) adjacency.AdjacencyGraph {
|
||||
var releventSubs adjacency.AdjacencyGraph
|
||||
for _, char := range password {
|
||||
if len(L33T_TABLE.Graph[string(char)]) > 0 {
|
||||
releventSubs.Graph[string(char)] = L33T_TABLE.Graph[string(char)]
|
||||
}
|
||||
}
|
||||
|
||||
return releventSubs
|
||||
}
|
||||
|
||||
//TODO yeah this is a little harder than i expect. . .
|
||||
//func enumerateL33tSubs(table adjacency.AdjacencyGraph) []string {
|
||||
// var subs [][]string
|
||||
//
|
||||
// dedup := func(subs []string) []string {
|
||||
// deduped := mapset.NewSetFromSlice(subs)
|
||||
// return deduped.ToSlice()
|
||||
// }
|
||||
//
|
||||
// for i,v := range table.Graph {
|
||||
// var nextSubs []string
|
||||
// for _, subChar := range v {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
||||
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 current == prev {
|
||||
currentStreak++
|
||||
|
||||
} else if currentStreak > 2 {
|
||||
iPos := i-currentStreak
|
||||
jPos := i-1
|
||||
matches = append(matches, match.Match{
|
||||
Pattern:"repeat",
|
||||
I:iPos,
|
||||
J:jPos,
|
||||
Token:password[iPos:jPos+1],
|
||||
RepeatedChar:prev})
|
||||
currentStreak = 1
|
||||
} else {
|
||||
currentStreak = 1
|
||||
}
|
||||
|
||||
prev = current
|
||||
}
|
||||
|
||||
if currentStreak > 2 {
|
||||
iPos := i - currentStreak+1
|
||||
jPos := i
|
||||
matches = append(matches, match.Match{
|
||||
Pattern:"repeat",
|
||||
I:iPos,
|
||||
J:jPos,
|
||||
Token:password[iPos:jPos + 1],
|
||||
RepeatedChar:prev})
|
||||
}
|
||||
return matches
|
||||
}
|
|
@ -15,9 +15,16 @@ const (
|
|||
START_UPPER string = `^[A-Z][^A-Z]+$`
|
||||
END_UPPER string = `^[^A-Z]+[A-Z]$'`
|
||||
ALL_UPPER string = `^[A-Z]+$`
|
||||
|
||||
//for a hash function like bcrypt/scrypt/PBKDF2, 10ms per guess is a safe lower bound.
|
||||
//(usually a guess would take longer -- this assumes fast hardware and a small work factor.)
|
||||
//adjust for your site accordingly if you use another hash function, possibly by
|
||||
//several orders of magnitude!
|
||||
SINGLE_GUESS float64 = 0.010
|
||||
NUM_ATTACKERS float64 = 100
|
||||
NUM_ATTACKERS float64 = 100 //Cores used to make guesses
|
||||
SECONDS_PER_GUESS float64 = SINGLE_GUESS / NUM_ATTACKERS
|
||||
|
||||
|
||||
)
|
||||
type MinEntropyMatch struct {
|
||||
Password string
|
||||
|
@ -126,18 +133,18 @@ func get(a []float64, i int) float64 {
|
|||
|
||||
return a[i]
|
||||
}
|
||||
func calcBruteforceCardinality(password string) int {
|
||||
lower, upper, digits, symbols := 0, 0, 0, 0
|
||||
func calcBruteforceCardinality(password string) float64 {
|
||||
lower, upper, digits, symbols := float64(0), float64(0), float64(0), float64(0)
|
||||
|
||||
for _, char := range password {
|
||||
if unicode.IsLower(char) {
|
||||
lower = 26
|
||||
lower = float64(26)
|
||||
} else if unicode.IsDigit(char) {
|
||||
digits = 10
|
||||
digits = float64(10)
|
||||
} else if unicode.IsUpper(char) {
|
||||
upper = 26
|
||||
upper = float64(26)
|
||||
} else {
|
||||
symbols = 33
|
||||
symbols = float64(33)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,6 +162,8 @@ func calcEntropy(match match.Match) float64 {
|
|||
entropy = dictionaryEntropy(match)
|
||||
} else if match.Pattern == "spatial" {
|
||||
entropy = spatialEntropy(match)
|
||||
} else if match.Pattern == "repeat" {
|
||||
entropy = repeatEntropy(match)
|
||||
}
|
||||
|
||||
match.Entropy = entropy
|
||||
|
@ -264,6 +273,13 @@ func extraUpperCaseEntropy(match match.Match) float64 {
|
|||
return float64(math.Log2(possibililities))
|
||||
}
|
||||
|
||||
func repeatEntropy(match match.Match) float64 {
|
||||
cardinality := calcBruteforceCardinality(match.Token)
|
||||
entropy := math.Log2(cardinality * float64(len(match.Token)))
|
||||
|
||||
return entropy
|
||||
}
|
||||
|
||||
func entropyToCrackTime(entropy float64) float64 {
|
||||
crackTime := (0.5 * math.Pow(float64(2), entropy)) * SECONDS_PER_GUESS
|
||||
|
||||
|
@ -275,7 +291,7 @@ func roundToXDigits(number float64, digits int) float64 {
|
|||
}
|
||||
|
||||
func displayTime(seconds float64) string {
|
||||
formater := "%d %s"
|
||||
formater := "%.1f %s"
|
||||
minute := float64(60)
|
||||
hour := minute * float64(60)
|
||||
day := hour * float64(24)
|
||||
|
|
|
@ -8,10 +8,10 @@ import (
|
|||
"zxcvbn-go/utils/math"
|
||||
)
|
||||
|
||||
func main() {
|
||||
password :="qw@!abcdPLSB$6D"
|
||||
fmt.Println(PasswordStrength(password, nil))
|
||||
}
|
||||
//func main() {
|
||||
// password :="Testaaatyhg890l33t"
|
||||
// fmt.Println(PasswordStrength(password, nil))
|
||||
//}
|
||||
|
||||
func PasswordStrength(password string, userInputs []string) scoring.MinEntropyMatch {
|
||||
start := time.Now()
|
||||
|
|
Loading…
Reference in New Issue