gitee.com/lonely0422/gometalinter.git@v3.0.1-0.20190307123442-32416ab75314+incompatible/_linters/src/github.com/nbutton23/zxcvbn-go/matching/dateMatchers.go (about) 1 package matching 2 3 import ( 4 "regexp" 5 "strconv" 6 "strings" 7 8 "github.com/nbutton23/zxcvbn-go/entropy" 9 "github.com/nbutton23/zxcvbn-go/match" 10 ) 11 12 const ( 13 DATESEP_MATCHER_NAME = "DATESEP" 14 DATEWITHOUTSEP_MATCHER_NAME = "DATEWITHOUT" 15 ) 16 17 func FilterDateSepMatcher(m match.Matcher) bool { 18 return m.ID == DATESEP_MATCHER_NAME 19 } 20 21 func FilterDateWithoutSepMatcher(m match.Matcher) bool { 22 return m.ID == DATEWITHOUTSEP_MATCHER_NAME 23 } 24 25 func checkDate(day, month, year int64) (bool, int64, int64, int64) { 26 if (12 <= month && month <= 31) && day <= 12 { 27 day, month = month, day 28 } 29 30 if day > 31 || month > 12 { 31 return false, 0, 0, 0 32 } 33 34 if !((1900 <= year && year <= 2019) || (0 <= year && year <= 99)) { 35 return false, 0, 0, 0 36 } 37 38 return true, day, month, year 39 } 40 41 func dateSepMatcher(password string) []match.Match { 42 dateMatches := dateSepMatchHelper(password) 43 44 var matches []match.Match 45 for _, dateMatch := range dateMatches { 46 match := match.Match{ 47 I: dateMatch.I, 48 J: dateMatch.J, 49 Entropy: entropy.DateEntropy(dateMatch), 50 DictionaryName: "date_match", 51 Token: dateMatch.Token, 52 } 53 54 matches = append(matches, match) 55 } 56 57 return matches 58 } 59 func dateSepMatchHelper(password string) []match.DateMatch { 60 61 var matches []match.DateMatch 62 63 matcher := regexp.MustCompile(DATE_RX_YEAR_SUFFIX) 64 for _, v := range matcher.FindAllString(password, len(password)) { 65 splitV := matcher.FindAllStringSubmatch(v, len(v)) 66 i := strings.Index(password, v) 67 j := i + len(v) 68 day, _ := strconv.ParseInt(splitV[0][4], 10, 16) 69 month, _ := strconv.ParseInt(splitV[0][2], 10, 16) 70 year, _ := strconv.ParseInt(splitV[0][6], 10, 16) 71 match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]} 72 matches = append(matches, match) 73 } 74 75 matcher = regexp.MustCompile(DATE_RX_YEAR_PREFIX) 76 for _, v := range matcher.FindAllString(password, len(password)) { 77 splitV := matcher.FindAllStringSubmatch(v, len(v)) 78 i := strings.Index(password, v) 79 j := i + len(v) 80 day, _ := strconv.ParseInt(splitV[0][4], 10, 16) 81 month, _ := strconv.ParseInt(splitV[0][6], 10, 16) 82 year, _ := strconv.ParseInt(splitV[0][2], 10, 16) 83 match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]} 84 matches = append(matches, match) 85 } 86 87 var out []match.DateMatch 88 for _, match := range matches { 89 if valid, day, month, year := checkDate(match.Day, match.Month, match.Year); valid { 90 match.Pattern = "date" 91 match.Day = day 92 match.Month = month 93 match.Year = year 94 out = append(out, match) 95 } 96 } 97 return out 98 99 } 100 101 type DateMatchCandidate struct { 102 DayMonth string 103 Year string 104 I, J int 105 } 106 107 type DateMatchCandidateTwo struct { 108 Day string 109 Month string 110 Year string 111 I, J int 112 } 113 114 func dateWithoutSepMatch(password string) []match.Match { 115 dateMatches := dateWithoutSepMatchHelper(password) 116 117 var matches []match.Match 118 for _, dateMatch := range dateMatches { 119 match := match.Match{ 120 I: dateMatch.I, 121 J: dateMatch.J, 122 Entropy: entropy.DateEntropy(dateMatch), 123 DictionaryName: "date_match", 124 Token: dateMatch.Token, 125 } 126 127 matches = append(matches, match) 128 } 129 130 return matches 131 } 132 133 //TODO Has issues with 6 digit dates 134 func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) { 135 matcher := regexp.MustCompile(DATE_WITHOUT_SEP_MATCH) 136 for _, v := range matcher.FindAllString(password, len(password)) { 137 i := strings.Index(password, v) 138 j := i + len(v) 139 length := len(v) 140 lastIndex := length - 1 141 var candidatesRoundOne []DateMatchCandidate 142 143 if length <= 6 { 144 //2-digit year prefix 145 candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[2:], v[0:2], i, j)) 146 147 //2-digityear suffix 148 candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-2], v[lastIndex-2:], i, j)) 149 } 150 if length >= 6 { 151 //4-digit year prefix 152 candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[4:], v[0:4], i, j)) 153 154 //4-digit year sufix 155 candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-3], v[lastIndex-3:], i, j)) 156 } 157 158 var candidatesRoundTwo []DateMatchCandidateTwo 159 for _, c := range candidatesRoundOne { 160 if len(c.DayMonth) == 2 { 161 candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:1], c.Year, c.I, c.J)) 162 } else if len(c.DayMonth) == 3 { 163 candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:2], c.Year, c.I, c.J)) 164 candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:3], c.Year, c.I, c.J)) 165 } else if len(c.DayMonth) == 4 { 166 candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:4], c.Year, c.I, c.J)) 167 } 168 } 169 170 for _, candidate := range candidatesRoundTwo { 171 intDay, err := strconv.ParseInt(candidate.Day, 10, 16) 172 if err != nil { 173 continue 174 } 175 176 intMonth, err := strconv.ParseInt(candidate.Month, 10, 16) 177 178 if err != nil { 179 continue 180 } 181 182 intYear, err := strconv.ParseInt(candidate.Year, 10, 16) 183 if err != nil { 184 continue 185 } 186 187 if ok, _, _, _ := checkDate(intDay, intMonth, intYear); ok { 188 matches = append(matches, match.DateMatch{Token: password, Pattern: "date", Day: intDay, Month: intMonth, Year: intYear, I: i, J: j}) 189 } 190 191 } 192 } 193 194 return matches 195 } 196 197 func buildDateMatchCandidate(dayMonth, year string, i, j int) DateMatchCandidate { 198 return DateMatchCandidate{DayMonth: dayMonth, Year: year, I: i, J: j} 199 } 200 201 func buildDateMatchCandidateTwo(day, month string, year string, i, j int) DateMatchCandidateTwo { 202 203 return DateMatchCandidateTwo{Day: day, Month: month, Year: year, I: i, J: j} 204 }