Generate random string [duplicate]
Possible Duplicate:
c# random string generator
I need to generate a random string with a given length. This is my code so far. The problem is the random string is like "RRRRRR" or "SSSSS" The same letter every time. Just when i restart the app the letter change. I need something like "asrDvgDgREGd"
public string GenerateChar()
{
Random random = new Random();
return Convert.ToChar(Convert.T开发者_运维百科oInt32(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;
}
Try using the same random object for the whole string, rather than initializing one for each char.
The random object will generate a "pseudo-random" number, based on mathematical progressions starting from a "seed" number. You can actually get the same sequence of "random" numbers if you initialize the Random object to the same seed every time.
Now, when you initialize Random without specifying a seed, it'll take the computer's clock as seed. In this case, you're probably doing it fast enough that the clock hasn't changed from one initialization to another, and you get always get the same seed.
You're better off initializing the Random object in your function that generates the random string, and passing it as a parameter to the GenerateChar function, so that you're calling NextDouble() several times on the same instance of the Random object, instead of only once on different instances of it.
You could save yourself the hassle and use Membership.GeneratePassword method. It is essentially doing what you require.
Usage:
int passwordLength = 5;
int alphaNumericalCharsAllowed = 2;
string random = Membership.GeneratePassword(passwordLength, alphaNumericalCharsAllowed);
For readability aswell you could wrap this in a helper method:
private string GenerateRandomString(int length, int alphaNumericalChars)
{
return Membership.GeneratePassword(length, alphaNumericalChars);
}
Don't create a new instance of Random
on each iteration - that's going to seed each instance with the current time in milliseconds, which obviously isn't likely to change between iterations.
Create a single instance of Random
, and pass it into the method. I'd also advise you not to concatenate strings like that in a loop, or even to create that many strings. Additionally, if you use Random.Next(int, int)
to make your life a lot easier.
Try this:
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);
}
Now it's worth being aware that Random
isn't thread-safe, so if you've got multiple threads you shouldn't just have a single instance of Random
in a static variable without locking. There are various ways around this - either create a subclass of Random
which is thread-safe, or a set of static methods which do the same thing, or use thread-local variables to have one instance per thread.
I have a StaticRandom
class as part of MiscUtil but these days I'm leaning towards the thread-local version and passing it down the chain where appropriate. One day I'll add that as another option to MiscUtil...
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());
}
I know this might not be the best solution, but I kind of like the idea to be able to specify "allowed" characters:
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();
}
Maybe you can find the Path.GetRandomFileName
method useful, depending on the exact characters you need in the string.
Try static
public string GenerateChar()
{
static Random random = new Random();
return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
}
http://msdn.microsoft.com/en-us/library/system.io.path.getrandomfilename.aspx
string randomName = Path.GetRandomFileName();
randomName = randomName.Replace(".", string.Empty);
// take substring...
Pass random
from the calling method and initialise it once - you are reseeding the Random generator with the same seed each time....
You should initialize your random variable outside the method:
public Random random = new Random();
public string GenerateChar()
{
return Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))).ToString();
}
...
Try this out.
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;
}
精彩评论