/// <summary> /// Asynchronously generates a password using the specified PasswordRecipe. /// </summary> /// <param name="recipe">A description of what constitutes a valid password to generate.</param> /// <returns>A Task responsible for generating the desired password.</returns> public Task <string> Generate(PasswordRecipe recipe) { if (recipe == null) { throw new ArgumentNullException(nameof(recipe)); } // Run the generation asynchronously because it could be expensive. return(Task.Run( () => { string newPassword = string.Empty; // Short circuit if there are no permissible characters left. if (recipe.AvailableCharacters.Count == 0) { return newPassword; } // Generate the password from the allowed chars (guaranteed to be good, now) for (int i = 0; i < recipe.Length; i++) { newPassword += recipe.AvailableCharacters[this.rngProvider.GetInt(recipe.AvailableCharacters.Count)]; } return newPassword; } )); }
public PasswordRecipe GetCurrentRecipe() { PasswordRecipe recipe = new PasswordRecipe(Length); if (UseLowerCase) { recipe.Include("abcdefghijklmnopqrstuvwxyz"); } if (UseUpperCase) { recipe.Include("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } if (UseDigits) { recipe.Include("0123456789"); } if (UseSpace) { recipe.Include(' '); } if (UseSymbols) { recipe.Include("!@#$%^&*/\\'\"`"); } if (UseBrackets) { recipe.Include("<>{}[]()"); } if (UseMinus) { recipe.Include('-'); } if (UseUnderscore) { recipe.Include('_'); } // Handle the final two lists of exceptions recipe.Include(AllowList); recipe.Exclude(ExcludeList); return(recipe); }