Ejemplo n.º 1
0
        private string GenerateInner(ActualPasswordGeneratorOptions options)
        {
            // at this point we expect options are validated and not null
            List <char>          password      = new List <char>();
            Action <string, int> generageGroup = (chars, length) =>
            {
                for (int i = 0; i < length; i++)
                {
                    password.Add(chars[_cr.NextInt(chars.Length)]);
                }
            };

            generageGroup(options.Numbers, options.NumbersLength);
            generageGroup(options.Upper, options.UpperLength);
            generageGroup(options.Lower, options.LowerLength);
            generageGroup(options.Symbols, options.SymbolsLength);

            password = ShuffleCharList(password);
            return(new string(password.ToArray()));
        }
        /// <summary>
        /// Generates actual options from this
        /// </summary>
        /// <returns>ActualPasswordGeneratorOptions</returns>
        internal ActualPasswordGeneratorOptions GetActuals()
        {
            var options = new ActualPasswordGeneratorOptions
            {
                Length        = (int)Length,
                Lower         = ValidLowerCase,
                Upper         = ValidUpperCase,
                Symbols       = ValidSymbols,
                LowerLength   = (int)MinLowerCase,
                UpperLength   = (int)MinUpperCase,
                NumbersLength = (int)MinNumbers,
                SymbolsLength = (int)MinSymbols
            };

            int maxLower   = 2 * options.LowerLength;
            int maxUpper   = 2 * options.UpperLength;
            int maxNumbers = 2 * options.NumbersLength;
            int maxSymbols = 2 * options.SymbolsLength;

            using (var cr = new CryptoRandom())
            {
                while (maxLower + maxUpper + maxNumbers + maxSymbols < options.Length)
                {
                    switch (cr.NextInt(4))
                    {
                    case 0:
                        if (maxLower != 0)
                        {
                            maxLower++;
                        }
                        break;

                    case 1:
                        if (maxUpper != 0)
                        {
                            maxUpper++;
                        }
                        break;

                    case 2:
                        if (maxSymbols != 0)
                        {
                            maxSymbols++;
                        }
                        break;

                    case 3:
                        if (maxNumbers != 0)
                        {
                            maxNumbers++;
                        }
                        break;

                    default:
                        throw new IndexOutOfRangeException();
                    }
                }

                Func <bool> canAddLower  = () => maxLower > options.LowerLength;
                Func <bool> canAddUpper  = () => maxUpper > options.UpperLength;
                Func <bool> canAddNumber = () => maxNumbers > options.NumbersLength;
                Func <bool> canAddSymbol = () => maxSymbols > options.SymbolsLength;

                while (options.Length != options.UpperLength + options.LowerLength + options.NumbersLength + options.SymbolsLength)
                {
                    switch (cr.NextInt(4))
                    {
                    case 0:
                        if (canAddLower())
                        {
                            options.LowerLength++;
                        }
                        break;

                    case 1:
                        if (canAddUpper())
                        {
                            options.UpperLength++;
                        }
                        break;

                    case 2:
                        if (canAddSymbol())
                        {
                            options.SymbolsLength++;
                        }
                        break;

                    case 3:
                        if (canAddNumber())
                        {
                            options.NumbersLength++;
                        }
                        break;

                    default:
                        throw new IndexOutOfRangeException();
                    }
                }
            }

            return(options);
        }