generate method

String generate({
  1. int length = 16,
  2. Random? random,
})

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.',
  );
}