Skip to content
This repository has been archived by the owner on Feb 1, 2023. It is now read-only.

Commit

Permalink
Changed to use the Python version as my base.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Button committed Oct 1, 2015
1 parent 21a0630 commit 441bbc2
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# zxcvbn-go
zxcvbn password complexity algorithm in golang

This is based off of the zxcvbn algorithm by Dropbox. https://github.com/dropbox/zxcvbn
This is based off of the zxcvbn algorithm by Dropbox. https://github.com/dropbox/python-zxcvbn

This is a work in progress
21 changes: 21 additions & 0 deletions adjacency/adjcmartix.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import (
"log"
"encoding/json"
"io/ioutil"
// "fmt"
)


Expand Down Expand Up @@ -58,3 +59,23 @@ func getAdjancencyGraphFromFile(filePath string) AdjacencyGraph {
return graph
}

//on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1.
//this calculates the average over all keys.
//TODO double check that i ported this correctly scoring.coffee ln 5
func (adjGrp AdjacencyGraph) CalculateAvgDegree() (float32) {
var avg float32
var count float32
for _, value := range adjGrp.Graph {

for _, char := range value {
if char != "" || char != " " {
avg += float32(len(char))
count++
}
}

}

return avg/count
}

150 changes: 150 additions & 0 deletions matching/matching.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package matching
import (
"strings"
"github.com/bradfitz/slice"
"regexp"
"strconv"
)

var DICTIONARY_MATCHERS []func(password string) []Match

const (
//TODO: Invalid regex for Golang since it has a \2
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}))`
)
type Match struct {
Pattern string
I, J int
Token string
MatchedWord string
Rank int
DictionaryName string
}

type DateMatch struct {
Pattern string
I, J int
Token string
Separator string
Day, Month, Year int64

}

func Omnimatch(password string, userInputs []string) []Match {
var rankedUserInputsDir map[string]int

for i, v := range userInputs {
rankedUserInputsDir[strings.ToLower(v)] = i+1
}
userInputMatcher := buildDictMatcher("user_inputs", rankedUserInputsDir)
matches := userInputMatcher(password)

for _, matcher := range DICTIONARY_MATCHERS {
mtemp := matcher(password)
for _,v:= range mtemp {
matches = append(matches, v)
}
}
slice.Sort(matches,func(i, j int)bool{
//TODO fix this
return false;
})
return matches
}




func buildDictMatcher(dictName string, rankedDict map[string]int) func(password string) []Match {
return func (password string) []Match{
matches := dictionaryMatch(password, rankedDict)
for _, v := range matches {
v.DictionaryName = dictName
}
return matches
}

}

func dictionaryMatch(password string, rankedDict map[string]int) []Match{
length := len(password)
var results []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 {
results = append(results, Match{Pattern:"dictionary",
I:i,
J:j,
Token:password[i:j+1],
MatchedWord:word,
Rank:val})
}
}
}

return results
}

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) {
return false, 0, 0, 0
}

return true, day, month, year
}

func DateSepMatch(password string) []DateMatch {

var matches []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 := DateMatch{Day:day, Month:month, Year:year, Separator:splitV[0][5], I:i, J: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 := DateMatch{Day:day, Month:month, Year:year, Separator:splitV[0][5], I:i, J:j }
matches = append(matches, match)
}

var out []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

}
28 changes: 28 additions & 0 deletions utils/math/mathutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package math



/**
I am surprised that I have to define these. . . Maybe i just didn't look hard enough for a lib.
*/

//http://blog.plover.com/math/choose.html
func NChoseK(n, k uint) uint64 {
uN := uint64(n)
uK := uint64(k)
if uK > uN {
return 0
} else if uK == 0 {
return 1
}

var r uint64 = 1

for d := uint64(1) ; d <= uK; d++ {
r *= uN
r /= d
uN--
}

return r
}
17 changes: 12 additions & 5 deletions zxcvbn.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package main

import (
// "zxcvbn-go/adjacency"
"zxcvbn-go/adjacency"
"fmt"
"zxcvbn-go/frequency"
"zxcvbn-go/utils/math"
"zxcvbn-go/matching"
)

func main(){
func main() {
fmt.Println("Start")
// fmt.Println(adjacency.AdjacencyGph)
fmt.Println(adjacency.AdjacencyGph.Qwerty.CalculateAvgDegree())
fmt.Println(adjacency.AdjacencyGph.Dvorak.CalculateAvgDegree())
fmt.Println(adjacency.AdjacencyGph.Keypad.CalculateAvgDegree())
fmt.Println(adjacency.AdjacencyGph.MacKeypad.CalculateAvgDegree())

fmt.Println(len(frequency.FreqLists.Passwords))

fmt.Println(math.NChoseK(100, 2))

fmt.Println(matching.DateSepMatch("1991-09-11jibjab11.9.1991"))
}

0 comments on commit 441bbc2

Please sign in to comment.