sequenceMatch.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package matching
  2. import (
  3. "strings"
  4. "github.com/nbutton23/zxcvbn-go/entropy"
  5. "github.com/nbutton23/zxcvbn-go/match"
  6. )
  7. const SEQUENCE_MATCHER_NAME = "SEQ"
  8. func FilterSequenceMatcher(m match.Matcher) bool {
  9. return m.ID == SEQUENCE_MATCHER_NAME
  10. }
  11. func sequenceMatch(password string) []match.Match {
  12. var matches []match.Match
  13. for i := 0; i < len(password); {
  14. j := i + 1
  15. var seq string
  16. var seqName string
  17. seqDirection := 0
  18. for seqCandidateName, seqCandidate := range SEQUENCES {
  19. iN := strings.Index(seqCandidate, string(password[i]))
  20. var jN int
  21. if j < len(password) {
  22. jN = strings.Index(seqCandidate, string(password[j]))
  23. } else {
  24. jN = -1
  25. }
  26. if iN > -1 && jN > -1 {
  27. direction := jN - iN
  28. if direction == 1 || direction == -1 {
  29. seq = seqCandidate
  30. seqName = seqCandidateName
  31. seqDirection = direction
  32. break
  33. }
  34. }
  35. }
  36. if seq != "" {
  37. for {
  38. var prevN, curN int
  39. if j < len(password) {
  40. prevChar, curChar := password[j-1], password[j]
  41. prevN, curN = strings.Index(seq, string(prevChar)), strings.Index(seq, string(curChar))
  42. }
  43. if j == len(password) || curN-prevN != seqDirection {
  44. if j-i > 2 {
  45. matchSequence := match.Match{
  46. Pattern: "sequence",
  47. I: i,
  48. J: j - 1,
  49. Token: password[i:j],
  50. DictionaryName: seqName,
  51. }
  52. matchSequence.Entropy = entropy.SequenceEntropy(matchSequence, len(seq), (seqDirection == 1))
  53. matches = append(matches, matchSequence)
  54. }
  55. break
  56. } else {
  57. j += 1
  58. }
  59. }
  60. }
  61. i = j
  62. }
  63. return matches
  64. }