Создать случайную строку
Возможный дубликат:
генератор случайных строк С#
Мне нужно создать случайную строку с заданной длиной. Это мой код до сих пор. Проблема заключается в том, что случайная строка похожа на "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();
}
Ответ 8
http://msdn.microsoft.com/en-us/library/system.io.path.getrandomfilename.aspx
string randomName = Path.GetRandomFileName();
randomName = randomName.Replace(".", string.Empty);
// take substring...
Ответ 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;
}