mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-15 08:41:16 -05:00
79 lines
1.5 KiB
Go
79 lines
1.5 KiB
Go
package matching
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"github.com/trustelem/zxcvbn/match"
|
|
)
|
|
|
|
type sequenceMatch struct{}
|
|
|
|
const maxDelta = 5
|
|
|
|
func abs(a int) int {
|
|
if a < 0 {
|
|
return -a
|
|
}
|
|
return a
|
|
}
|
|
|
|
var reLower = regexp.MustCompile(`^[a-z]+$`)
|
|
var reUpper = regexp.MustCompile(`^[A-Z]+$`)
|
|
var reDigits = regexp.MustCompile(`^\d+$`)
|
|
|
|
func (sequenceMatch) Matches(password string) []*match.Match {
|
|
matches := []*match.Match{}
|
|
if len(password) == 1 {
|
|
return matches
|
|
}
|
|
|
|
update := func(i, j, delta int) {
|
|
absDelta := abs(delta)
|
|
if j-i > 1 || absDelta == 1 {
|
|
if absDelta > 0 && absDelta <= maxDelta {
|
|
token := password[i : j+1]
|
|
// conservatively stick with roman alphabet size.
|
|
// (this could be improved)
|
|
seqName := "unicode"
|
|
seqSpace := 26
|
|
if reLower.MatchString(token) {
|
|
seqName = "lower"
|
|
} else if reUpper.MatchString(token) {
|
|
seqName = "upper"
|
|
} else if reDigits.MatchString(token) {
|
|
seqName = "digits"
|
|
seqSpace = 10
|
|
}
|
|
matches = append(matches, &match.Match{
|
|
Pattern: "sequence",
|
|
I: i,
|
|
J: j,
|
|
Token: password[i : j+1],
|
|
SequenceName: seqName,
|
|
SequenceSpace: seqSpace,
|
|
Ascending: delta > 0,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
i := 0
|
|
lastDelta := 0 // null
|
|
for k := 1; k <= len(password)-1; k++ {
|
|
delta := int(password[k]) - int(password[k-1])
|
|
if k == 1 {
|
|
lastDelta = delta
|
|
}
|
|
if delta == lastDelta {
|
|
continue
|
|
}
|
|
j := k - 1
|
|
update(i, j, lastDelta)
|
|
i = j
|
|
lastDelta = delta
|
|
}
|
|
|
|
update(i, len(password)-1, lastDelta)
|
|
return matches
|
|
}
|