Создать случайную строку

Возможный дубликат:
генератор случайных строк С#

Мне нужно создать случайную строку с заданной длиной. Это мой код до сих пор. Проблема заключается в том, что случайная строка похожа на "RRRRRR" или "SSSSS". Эта же буква каждый раз. Когда я перезапущу приложение, письмо изменится. Мне нужно что-то вроде "asrDvgDgREGd"

    public string GenerateChar()
    {
        Random random = new Random();

        return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
    }

    public string GenerateChar(int count)
    {        
        string randomString = "";

        for (int i = 0; i < count; i++)
        {
            nahodneZnaky += GenerateChar();
        }

        return randomString;
    }

Ответ 1

Попробуйте использовать один и тот же случайный объект для всей строки, а не инициализировать один для каждого char.

Случайный объект будет генерировать "псевдослучайное" число, основанное на математических прогрессиях, начиная с "семенного" числа. Фактически вы можете получить одну и ту же последовательность "случайных" чисел, если каждый раз инициализировать объект Random одним и тем же семенем.

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

Вам лучше инициализировать объект Random в вашей функции, который генерирует случайную строку и передавая ее как параметр функции GenerateChar, так что вы вызываете NextDouble() несколько раз в том же экземпляре Random объект, а не только один раз в разных экземплярах.

Ответ 2

Вы могли бы сэкономить нервы и использовать метод Membership.GeneratePassword. Это по сути делает то, что вам нужно.

Использование:

int passwordLength = 5;
int alphaNumericalCharsAllowed = 2;
string random = Membership.GeneratePassword(passwordLength, alphaNumericalCharsAllowed);

Для удобства чтения вы можете обернуть это методом помощника:

private string GenerateRandomString(int length, int alphaNumericalChars)
{
      return Membership.GeneratePassword(length, alphaNumericalChars);
}

Ответ 3

Не создавайте новый экземпляр Random на каждой итерации, который будет засеять каждый экземпляр текущим временем в миллисекундах, что, очевидно, вряд ли изменится между итерациями.

Создайте один экземпляр Random и передайте его в метод. Я бы также посоветовал вам не конкатенировать такие строки в цикле или даже создавать множество строк. Кроме того, если вы используете Random.Next(int, int), чтобы сделать вашу жизнь намного проще.

Попробуйте следующее:

public char GenerateChar(Random rng)
{
    // 'Z' + 1 because the range is exclusive
    return (char) (rng.Next('A', 'Z' + 1));
}

public string GenerateString(Random rng, int length)
{ 
    char[] letters = new char[length];
    for (int i = 0; i < length; i++)
    {
        letters[i] = GenerateChar(rng);
    }
    return new string(letters);
}

private static readonly Random SingleRandom = new Random();

public string GenerateStringNotThreadSafe(int length)
{ 
    return GenerateString(SingleRandom, length);
}

Теперь стоит знать, что Random не является потокобезопасным, поэтому, если у вас есть несколько потоков, у вас не должно быть только одного экземпляра Random в статической переменной без блокировки. Существуют различные способы обойти это: либо создайте подкласс Random, который является потокобезопасным, либо набор статических методов, которые делают то же самое, или используют потоковые локальные переменные, чтобы иметь один экземпляр для потока.

У меня есть StaticRandom класс как часть MiscUtil, но в эти дни я склоняюсь к локальной локальной версии и передаю ее по цепочке, где это необходимо. Однажды я добавлю это как еще один вариант в MiscUtil...

Ответ 4

Ничего особенного, но короткого. 32 и 127 - это минимальный и максимальный диапазон символов, которые вы хотите сгенерировать.

public static string GetRandomString(int length)
{
    var r = new Random();
    return new String(Enumerable.Range(0, length).Select(n => (Char)(r.Next(32, 127))).ToArray());
}

Ответ 5

Я знаю, что это может быть не лучшее решение, но я вроде как идея указать "разрешенные" символы:

    private const int _defaultNumberOfCharacters = 8;
    private const int _defaultExpireDays = 10;
    private static readonly string _allowedCharacters = "bcdfghjklmnpqrstvxz0123456789";

    public static string GenerateKey(int numberOfCharacters)
    {
        const int from = 0;
        int to = _allowedCharacters.Length;
        Random r = new Random();

        StringBuilder qs = new StringBuilder();
        for (int i = 0; i < numberOfCharacters; i++)
        {
            qs.Append(_allowedCharacters.Substring(r.Next(from, to), 1));
        }
        return qs.ToString();
    }

Ответ 6

Возможно, вы можете найти метод Path.GetRandomFileName в зависимости от точных символов, которые вам нужны в строке.

Ответ 7

Попробуйте static

public string GenerateChar()
{
    static Random random = new Random();

    return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
}

Ответ 9

Передайте random из вызывающего метода и инициализируйте его один раз - вы каждый раз подбираете генератор случайных событий с одним и тем же семенем....

Ответ 10

Вы должны инициализировать свою случайную переменную вне метода:

public Random random = new Random();

public string GenerateChar()
    {
       return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
    }

...

Ответ 11

Попробуйте это.

public string GetRandomString()
{
    int randomNumber = new Random().Next();
    string RandomString = string.Empty;
    for(int i = 0;i < randomNumber.ToString().Length;i++)
    {
        RandomString += ((char)Convert.ToUInt32(randomNumber.ToString()[i])).ToString();
    }
    return RandomString;
}