Merge pull request #1 from nbutton23/button-repeating-match

Button repeating match
This commit is contained in:
Nathan Button 2015-10-06 16:19:28 -06:00
commit 9acbd57b69
6 changed files with 167 additions and 16 deletions

51
adjacency/L33t.json Normal file
View File

@ -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"
]
}
}

View File

@ -9,7 +9,7 @@ import (
type AdjacencyGraph struct {
Graph map[string][6]string
Graph map[string][]string
averageDegree float64
Name string
}

View File

@ -26,6 +26,7 @@ type Match struct {
Turns int
ShiftedCount int
Entropy float64
RepeatedChar string
}
type DateMatch struct {

View File

@ -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
}

View File

@ -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)

View File

@ -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()