using System; using System.Collections.Generic; using System.Linq; namespace Chrosey.Extensions.Helper { public class PasswordGenerator { private readonly RandomSecureVersion _randomSecure = new RandomSecureVersion(); private readonly string _allAvailableChars; private int _minimumNumberOfChars; public int MinimumLengthPassword { get; private set; } public int MaximumLengthPassword { get; private set; } public int MinimumLowerCaseChars { get; private set; } public int MinimumUpperCaseChars { get; private set; } public int MinimumNumericChars { get; private set; } public int MinimumSpecialChars { get; private set; } public static string AllLowerCaseChars { get; private set; } public static string AllUpperCaseChars { get; private set; } public static string AllNumericChars { get; private set; } public static string AllSpecialChars { get; private set; } static PasswordGenerator() { PasswordGenerator.AllLowerCaseChars = PasswordGenerator.GetCharRange('a', 'z', ""); PasswordGenerator.AllUpperCaseChars = PasswordGenerator.GetCharRange('A', 'Z', ""); PasswordGenerator.AllNumericChars = PasswordGenerator.GetCharRange('0', '9', ""); PasswordGenerator.AllSpecialChars = "#?!@$%^&*-"; } public PasswordGenerator( int minimumLengthPassword = 8, int maximumLengthPassword = 15, int minimumLowerCaseChars = 2, int minimumUpperCaseChars = 1, int minimumNumericChars = 3, int minimumSpecialChars = 1) { if (minimumLengthPassword < 1) throw new ArgumentException("The minimumlength is smaller than 1.", nameof(minimumLengthPassword)); if (minimumLengthPassword > maximumLengthPassword) throw new ArgumentException("The minimumLength is bigger than the maximum length.", nameof(minimumLengthPassword)); if (minimumLowerCaseChars < 0) throw new ArgumentException("The minimumLowerCase is smaller than 0.", nameof(minimumLowerCaseChars)); if (minimumUpperCaseChars < 0) throw new ArgumentException("The minimumUpperCase is smaller than 0.", nameof(minimumUpperCaseChars)); if (minimumNumericChars < 0) throw new ArgumentException("The minimumNumeric is smaller than 0.", nameof(minimumNumericChars)); if (minimumSpecialChars < 0) throw new ArgumentException("The minimumSpecial is smaller than 0.", nameof(minimumSpecialChars)); this._minimumNumberOfChars = minimumLowerCaseChars + minimumUpperCaseChars + minimumNumericChars + minimumSpecialChars; if (minimumLengthPassword < this._minimumNumberOfChars) throw new ArgumentException("The minimum length ot the password is smaller than the sum of the minimum characters of all catagories.", nameof(maximumLengthPassword)); this.MinimumLengthPassword = minimumLengthPassword; this.MaximumLengthPassword = maximumLengthPassword; this.MinimumLowerCaseChars = minimumLowerCaseChars; this.MinimumUpperCaseChars = minimumUpperCaseChars; this.MinimumNumericChars = minimumNumericChars; this.MinimumSpecialChars = minimumSpecialChars; this._allAvailableChars = this.OnlyIfOneCharIsRequired(minimumLowerCaseChars, PasswordGenerator.AllLowerCaseChars) + this.OnlyIfOneCharIsRequired(minimumUpperCaseChars, PasswordGenerator.AllUpperCaseChars) + this.OnlyIfOneCharIsRequired(minimumNumericChars, PasswordGenerator.AllNumericChars) + this.OnlyIfOneCharIsRequired(minimumSpecialChars, PasswordGenerator.AllSpecialChars); } private string OnlyIfOneCharIsRequired(int minimum, string allChars) { return minimum > 0 || this._minimumNumberOfChars == 0 ? allChars : string.Empty; } public string Generate() { int num = this._randomSecure.Next(this.MinimumLengthPassword, this.MaximumLengthPassword); string str = this.GetRandomString(PasswordGenerator.AllLowerCaseChars, this.MinimumLowerCaseChars) + this.GetRandomString(PasswordGenerator.AllUpperCaseChars, this.MinimumUpperCaseChars) + this.GetRandomString(PasswordGenerator.AllNumericChars, this.MinimumNumericChars) + this.GetRandomString(PasswordGenerator.AllSpecialChars, this.MinimumSpecialChars); string randomString = this.GetRandomString(this._allAvailableChars, num - str.Length); return (str + randomString).ShuffleTextSecure(); } private string GetRandomString(string possibleChars, int lenght) { string empty = string.Empty; for (int index1 = 0; index1 < lenght; ++index1) { int index2 = this._randomSecure.Next(possibleChars.Length); empty += possibleChars[index2].ToString(); } return empty; } private static string GetCharRange(char minimum, char maximum, string exclusiveChars = "") { string first = string.Empty; for (char ch = minimum; (int)ch <= (int)maximum; ++ch) first += ch.ToString(); if (!string.IsNullOrEmpty(exclusiveChars)) first = new string(first.Except((IEnumerable)exclusiveChars).ToArray()); return first; } } }