Задать вопрос
@vladimirchelyabinskiy

C# как генерировать символы без повторений?

имеется скрипт

private static string GenerateRandomPassword(int passwordLength, int type)
        {
            const string allowedChars = "abcdefghijkmnopqrstuvwxyz";
            const string allowedCharsWithCaps = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
            const string allowedCharsWithCapsAndNumbers = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
            const string allowedCharsWithCapsAndNumbersAndSymbols = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!@$?_-";

            char[] chars = new char[passwordLength];
            Random rd = new Random();
            string passwordCombinations;

            switch (type)
            {
                case 1:
                    passwordCombinations = allowedChars;
                    break;
                case 2:
                    passwordCombinations = allowedCharsWithCaps;
                    break;
                case 3:
                    passwordCombinations = allowedCharsWithCapsAndNumbers;
                    break;
                case 4:
                    passwordCombinations = allowedCharsWithCapsAndNumbersAndSymbols;
                    break;
                default:
                    passwordCombinations = allowedChars;
                    break;
            }

            for (int i = 0; i < passwordLength; i++)
            {
                chars[i] = passwordCombinations[rd.Next(0, passwordCombinations.Length - 1)];
            }

            return new string(chars);
        }


далее в цикле использую для генерации паролей но он генерирует с повторениями.... как сделать что бы по достижению максимальной комбинации того или иного типа генерации программа заканчивала работу break

то есть я указал количество символов в строке 4 и тип allowedChars = "abcdefghijkmnopqrstuvwxyz"; программа сгенерировала максимально возможные комбинации без повторений и вышла из цикла.
  • Вопрос задан
  • 4461 просмотр
Подписаться 2 Оценить 2 комментария
Решения вопроса 1
barkalov
@barkalov
то есть я указал количество символов в строке 4 и тип allowedChars = "abcdefghijkmnopqrstuvwxyz"; программа сгенерировала максимально возможные комбинации без повторений и вышла из цикла.
этих комбинаций, кстати, 390 625 штук. Math.Pow(alphabetLength, passwordLength)

Если вам нужно сгенерировать, условно, 100 уникальных 10 символьных паролей, то вот наивный код:
private static HashSet<string> GenerateSomeRandomPasswords(int passwordCount, int passwordLength, int type)
{
    HashSet<string> passwords = new HashSet<string>();
    int addedPasswordCount = 0;
    while (addedPasswordCount<passwordCount)
    {
        string freshPassword = GenerateRandomPassword(passwordLength, type);
        if (passwords.Contains(freshPassword)==false)
        {
            passwords.Add(freshPassword);
            addedPasswordCount++;
        }
    }
    return passwords;
}
( проверка того, чтобы passwordCount не превышал разумные пределы — за вами )

Если вам, вдруг, нужно сгенерировать больше половины всех возможных паролей, или вообще весь набор, задача решается принципиально иначе. Напишите камент, если вы об этом.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Shetani
Цикл с генерацией пароля запихнуть в цикл, который контролирует кол-во генерируемых паролей.

Для генерации паролей без повторений надо из набора символов удалять символ, который был выбран для пароля, после генерации первого пароля исходный набор символов надо будет обновить.
Ответ написан
Комментировать
lam0x86
@lam0x86
Во-первых, в коде баг: rd.Next(0, passwordCombinations.Length - 1)] никогда не вернёт последний символ.

Во-вторых, Random rd = new Random(); использует Environment.TickCount в качестве seed-а. Если метод вызывается несколько раз в миллисекунду, он вернёт одинаковый результат. Вам нужно создать экземпляр класса Random один раз и передавать его в метод. А ещё лучше - использовать System.Security.Cryptography.RandomNumberGenerator.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы