143 lines
4.0 KiB
Go
143 lines
4.0 KiB
Go
package matching
|
|
|
|
import (
|
|
"github.com/nbutton23/zxcvbn-go/match"
|
|
"strings"
|
|
"regexp"
|
|
"strconv"
|
|
"github.com/nbutton23/zxcvbn-go/entropy"
|
|
)
|
|
|
|
|
|
|
|
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 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
|
|
}
|
|
|
|
//TODO I think Im doing this wrong.
|
|
func dateWithoutSepMatch(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-4], v[lastIndex-4:], i, j))
|
|
}
|
|
|
|
var candidatesRoundTwo []match.DateMatch
|
|
for _, c := range candidatesRoundOne {
|
|
if len(c.DayMonth) == 2 {
|
|
candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0], c.DayMonth[1], c.Year, c.I, c.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 byte, year string, i, j int) match.DateMatch {
|
|
sDay := string(day)
|
|
sMonth := string(month)
|
|
intDay, _ := strconv.ParseInt(sDay, 10, 16)
|
|
intMonth, _ := strconv.ParseInt(sMonth, 10, 16)
|
|
intYear, _ := strconv.ParseInt(year, 10, 16)
|
|
|
|
return match.DateMatch{Day: intDay, Month: intMonth, Year: intYear, I: i, J: j}
|
|
}
|