Генерируйте случайную строку [дубликат]

Главная причина для кода модульного теста во-первых состоит в том, чтобы проверить дизайн Вашего кода. Возможно получить 100%-е покрытие кода, но не используя фиктивные объекты или некоторую форму изоляции или внедрения зависимости.

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

16
задан Community 23 May 2017 в 11:46
поделиться

9 ответов

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

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

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

Лучше инициализировать объект Random в вашей функции, который генерирует случайную строку и передает ее в качестве параметра функции GenerateChar,

26
ответ дан 30 November 2019 в 15:08
поделиться

Вы можете избавить себя от хлопот и использовать метод 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);
}
19
ответ дан 30 November 2019 в 15:08
поделиться

Попробуйте static

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

    return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
}
1
ответ дан 30 November 2019 в 15:08
поделиться

Не создавайте новый экземпляр 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 ...

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

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

13
ответ дан 30 November 2019 в 15:08
поделиться

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

    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();
    }
4
ответ дан 30 November 2019 в 15:08
поделиться

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

1
ответ дан 30 November 2019 в 15:08
поделиться

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

public Random random = new Random();

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

...
0
ответ дан 30 November 2019 в 15:08
поделиться

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

0
ответ дан 30 November 2019 в 15:08
поделиться

Nothing special, but short. 32 and 127 are min and max range of chars you want to be generated.

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());
}
9
ответ дан 30 November 2019 в 15:08
поделиться