Files
skills/docs/security-stack/security/password-strength/src/matchers/repeat/repeat.md
2026-05-29 08:20:56 +01:00

2.2 KiB

repeat — repeated-chunk pattern matcher

(no submodules)

Purpose

Finds every maximal substring composed of a repeating chunk (e.g. aaaa, abcabc, babababa) per Wheeler 2016 section 3.3. The chunk's strength is estimated by recursively running mostGuessableMatchSequence on the chunk itself with the same dictionary set — a password like passwordpassword gets the dictionary's rank-1 strength times the repeat-count factor.

Features

  • Detects single-character and multi-character repeats
  • Picks the longer of greedy and lazy chunk candidates so the matcher does not prefer aa four times over aaaa once
  • Recursive baseGuesses via mostGuessableMatchSequence
  • Carries the recursive baseMatches so consumers can inspect the chunk's own cover

Usage: Basic Example

import { repeatMatch } from "@suaveplan/password-strength/matchers/repeat";

const matches = repeatMatch("aaaa", {});
console.log(matches[0].baseToken); // "a"
console.log(matches[0].repeatCount); // 4

Usage: Advanced Example

import { repeatMatch } from "@suaveplan/password-strength/matchers/repeat";

const dicts = { passwords: new Map([["password", 1]]) };
const matches = repeatMatch("passwordpassword", dicts);
for (const m of matches) {
 console.log(m.baseToken, m.repeatCount, m.baseGuesses);
}

API Reference

  • repeatMatch(password: string, dictionaries: DictionarySet): RepeatMatch[]
    • Returns every maximal repeat-of-chunk substring. The dictionary set is threaded into the chunk's recursive scoring so dictionary words appearing inside the chunk inherit their rank.

Implementation Notes

The matcher runs both a greedy and a lazy chunk regex from each candidate start position and picks whichever produces the longer overall repeat. Greedy finds the longest possible chunk that still repeats at least once; lazy finds the smallest. Picking the longer span avoids over-fragmenting a real repeat into two adjacent shorter ones with the same characters. The recursive scoring call uses the dictionary and sequence matchers — recursive keyboard or date matching inside a chunk is rare in practice and intentionally excluded for performance under the 200-character DoS guard.