Является ли это хорошим способом генерации строки случайных символов?

Я нашел этот фрагмент кода, который генерирует строку случайных символов.

Но есть ли более элегантный/более быстрый/более надежный способ сделать это? Это, по-видимому, полагается на то, что числа 26-91 являются допустимыми символами с учетом текущей кодировки.

/// <summary>
/// Generates a random string with the given length
/// </summary>
/// <param name="size">Size of the string</param>
/// <param name="lowerCase">If true, generate lowercase string</param>
/// <returns>Random string</returns>
private string RandomString(int size, bool lowerCase)
{
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    char ch;

    for(int i = 0; i < size; i++)
    {
        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
        builder.Append(ch);
    }

    if(lowerCase)
        return builder.ToString().ToLower();

    return builder.ToString();
}

Ответ 1

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

public const string LowerCaseAlphabet = "abcdefghijklmnopqrstuvwyxz";
public const string UpperCaseAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

public static string GenerateUpperCaseString(int size, Random rng)
{
    return GenerateString(size, rng, UpperCaseAlphabet);
}

public static string GenerateLowerCaseString(int size, Random rng)
{
    return GenerateString(size, rng, LowerCaseAlphabet);
}

public static string GenerateString(int size, Random rng, string alphabet)
{
    char[] chars = new char[size];
    for (int i=0; i < size; i++)
    {
        chars[i] = alphabet[rng.Next(alphabet.Length)];
    }
    return new string(chars);
}
  • Нет необходимости использовать StringBuilder, когда вы знаете конечную длину
  • Использование Random.NextDouble() указывает на отсутствие знаний о классе Random. (В частности, Random.Next(int, int)
  • Создание нового Random в каждом вызове может привести к дублированию строк
  • Вызов Convert.ToInt32 и Convert.ToChar кажется уродливым по сравнению с простое литье
  • Нижняя часть корпуса кажется бессмысленной по сравнению с выбором строчных букв для начала с
  • Предоставление алфавита для выбора гораздо более гибкое (с помощью вспомогательных методов для обычных случаев).

Ответ 2

Если бы я сделал это (и у меня было, но на Java, где-то безводно), я бы предоставил массив допустимых символов и использовал RNG просто для того, чтобы выбрать индекс символа. Это также позволит вам запретить символы, которые вы не хотите генерировать (если вы создаете лицензионный ключ с правами человека, вы не хотите генерировать символы, которые могут быть смущены друг с другом, например, 0 и O, или 1 и 1).

РЕДАКТИРОВАТЬ: да, как это сделал Джон...

Ответ 3

Path.GetRandomFileName()

string randomName = Path.GetRandomFileName();
randomName = randomName.Replace(".", string.Empty);

// take substring...