generate method
Builds a random ASCII password that satisfies every active rule.
The result has length characters, grown to fit minLength and the
counts and shrunk to maxLength. random defaults to
Random.secure. MatchRule is skipped. Throws an ArgumentError
when the counts cannot fit in maxLength and a StateError when a
CustomRule rejects every candidate.
Implementation
String generate({int length = 16, Random? random}) {
final source = random ?? Random.secure();
final required = _requiredCharacters(source);
var targetLength = max(length, max(minLength, required.length));
if (maxLength > 0) {
targetLength = min(targetLength, maxLength);
}
if (targetLength < required.length) {
throw ArgumentError(
'The rule counts need ${required.length} characters but maxLength is '
'$maxLength.',
);
}
for (var attempt = 0; attempt < _generateAttempts; attempt++) {
final characters = [
...required,
for (var index = required.length; index < targetLength; index++)
_pick(_generatedAny, source),
]..shuffle(source);
final candidate = characters.join();
if (_acceptsGenerated(candidate)) {
return candidate;
}
required
..clear()
..addAll(_requiredCharacters(source));
}
throw StateError(
'No generated password satisfied the rules in $_generateAttempts '
'attempts.',
);
}