229

I've developed a random string generator but it's not behaving quite as I'm hoping. My goal is to be able to run this twice and generate two distinct four character random strings. However, it just generates one four character random string twice.

Here's the code and an example of its output:

private string RandomString(int size)
{
    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);
    }

    return builder.ToString();
}

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// create full rand string
string docNum = Rand1 + "-" + Rand2;

...and the output looks like this: UNTE-UNTE ...but it should look something like this UNTE-FWNU

How can I ensure two distinctly random strings?

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
PushCode
  • 3,077
  • 4
  • 25
  • 26
  • http://stackoverflow.com/questions/4616685/how-to-generate-a-random-string-and-specify-the-length-you-want-or-better-gene/7977737#7977737 Good Performance – mola10 Nov 02 '11 at 08:58
  • 3
    Note that even two perfectly random strings aren't guaranteed to be unique. With long strings (120+ bits) it's extremely likely that they're unique, but with short strings like this, collisions are common. – CodesInChaos Nov 19 '12 at 10:03
  • Old thread but ... if it suits, you could generate a GUID and convert it to text. – user3657408 Feb 28 '20 at 19:27

30 Answers30

312

You're making the Random instance in the method, which causes it to return the same values when called in quick succession. I would do something like this:

private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private string RandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        char ch;
        for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));                 
            builder.Append(ch);
        }

        return builder.ToString();
    }

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// creat full rand string
string docNum = Rand1 + "-" + Rand2;

(modified version of your code)

RCIX
  • 38,647
  • 50
  • 150
  • 207
  • 47
    Note that instance members of the `Random` class are NOT documented as being thread-safe, so if this method is called from multiple threads at the same time (highly likely if you're making a web app, for example) then the behaviour of this code will be undefined. You either need to use a lock on the random or make it per-thread. – Greg Beech Oct 14 '10 at 18:27
  • yes random is not thread safe and causes a lot of problems at asp.net website – Furkan Gözükara Dec 26 '12 at 14:40
  • 19
    Also, you can get a random uppercase letter by using `ch = (char)random.Next('A','Z');` a lot simpler than the unreadable line `ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));` from the original post. Then if you want to switch it to lowercase, you can easily switch to `(char)random.Next('a','z');` – Nick Freeman Apr 11 '13 at 14:43
  • 17
    @NickFreeman: Remember [the upper bound is exclusive](http://msdn.microsoft.com/en-us/library/2dx6wyd4.aspx), so `ch = (char)random.Next('A','Z');` would never return `'Z'`. So you'd need `ch = (char)random.Next('A', 'Z' + 1);` to include the `'Z'`. – T.J. Crowder May 30 '13 at 13:49
  • If called in immediate succession it gives the same letter. – shubniggurath Jan 09 '14 at 21:54
  • A possible linq way: Enumerable.Range(0,4).Select(c => (char)rand.Next('a', 'z' + 1)).ToArray(); – Jason Slocomb Mar 10 '14 at 17:09
  • 1
    I actually use `new Random(Guid.NewGuid().GetHashCode());` for a seed instead of relying on `DateTime`. – Filipe Leite Nov 07 '14 at 16:16
190

You're instantiating the Random object inside your method.

The Random object is seeded from the system clock, which means that if you call your method several times in quick succession it'll use the same seed each time, which means that it'll generate the same sequence of random numbers, which means that you'll get the same string.

To solve the problem, move your Random instance outside of the method itself (and while you're at it you could get rid of that crazy sequence of calls to Convert and Floor and NextDouble):

private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

private string RandomString(int size)
{
    char[] buffer = new char[size];

    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[_rng.Next(_chars.Length)];
    }
    return new string(buffer);
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • 7
    Or make it static and internal to the class. – Jake Pearson Jul 13 '09 at 22:50
  • 9
    Also, I like making this sort of method an extension method on Random. – Cameron MacFarland Jul 13 '09 at 23:08
  • 8
    Note that instance members of the Random class are NOT documented as being thread-safe, so if this method is called from multiple threads at the same time (highly likely if you're making a web app, for example) then the behaviour of this code will be undefined. You either need to use a lock on the random or make it per-thread. – Greg Beech Oct 14 '10 at 18:28
137

A very simple implementation that uses Path.GetRandomFileName():

using System.IO;   
public static string RandomStr()
{
    string rStr = Path.GetRandomFileName();
    rStr = rStr.Replace(".", ""); // For Removing the .
    return rStr;
}

Now just call RandomStr().

Pang
  • 9,564
  • 146
  • 81
  • 122
Ranvir
  • 2,094
  • 2
  • 19
  • 26
  • I like this method better than the others listed. Good find. – Graham Apr 18 '11 at 03:26
  • 7
    nice! Love it when you find a little gem like GetRandomFileName hidden in the .Net framework – Andy Britcliffe Apr 20 '11 at 09:23
  • +1 - Used this today - love it! – LeopardSkinPillBoxHat Dec 20 '11 at 05:12
  • 2
    Used yours with a slight edit. guid = Guid.NewGuid(); mystring = guid.ToString(); mystring = mystring.Replace("-", ""); mystring = mystring.Substring(0, 8); – Andrew Jan 13 '12 at 16:53
  • 1
    @Andrew You're probably reducing the randomness quite a bit when you use just a substring of the guid. – Anders Fjeldstad Jan 23 '12 at 18:55
  • 3
    @AndersFjeldstad Agreed, I did a loop and it hits a collision after approximately 130,000 iterations. Even though there are 1,785,793,904,896 combinations. – Andrew Jan 24 '12 at 12:54
  • 18
    This creates files on the disk. From MSDN: The GetTempFileName method will raise an IOException if it is used to create more than 65535 files without deleting previous temporary files. The GetTempFileName method will raise an IOException if no unique temporary file name is available. To resolve this error, delete all unneeded temporary files. – bugnuker Jul 24 '12 at 21:51
  • 25
    @bugnuker "The GetRandomFileName method returns a cryptographically strong, random string that can be used as either a folder name or a file name. Unlike GetTempFileName, GetRandomFileName does not create a file. When the security of your file system is paramount, this method should be used instead of GetTempFileName." We are talking about GetRandomFileName() not GetTempFileName(). – quantum Nov 07 '12 at 02:27
  • Smart, nice and simple. Love it :P – Ignacio Soler Garcia Jun 21 '13 at 07:33
49

As long as you are using Asp.Net 2.0 or greater, you can also use the library call- System.Web.Security.Membership.GeneratePassword, however it will include special characters.

To get 4 random characters with minimum of 0 special characters-

Membership.GeneratePassword(4, 0)
Spongeboy
  • 2,232
  • 3
  • 28
  • 37
  • 9
    Note that in 4.0 the second integer parameter denotes the **minimum** number of nonAlphaNumericCharacters to use. So `Membership.GeneratePassword(10, 0);` won't work quite the way you think, it still puts in loads of non-alphanumeric characters, eg: `z9sge)?pmV` – keithl8041 Aug 19 '11 at 11:01
  • the only reason i can think of for not wanting to using this over other methods is the hassle you have to go through to remove special characters....... assuming you need to which i don't – Ben Apr 17 '12 at 13:32
  • Thanks keithl8041, updated answer to reflect that. – Spongeboy Jun 12 '12 at 06:05
  • For me this is the correct answer as long as you have access to membership. I mean why reinvent hot water right? – Marko Feb 22 '13 at 22:09
22

Just for people stopping by and what to have a random string in just one single line of code

int yourRandomStringLength = 12; //maximum: 32
Guid.NewGuid().ToString("N").Substring(0, yourRandomStringLength);

PS: Please keep in mind that yourRandomStringLength cannot exceed 32 as Guid has max length of 32.

Abdul Munim
  • 18,869
  • 8
  • 52
  • 61
  • 9
    I'm not sure that will necessarily be random. GUIDs are designed to be unique, not random, so it's possible the first N characters in string could be identical (depending on the GUID generator). – cdmckay Jun 25 '12 at 14:28
  • 1
    I just needed a 5 character temp password to hash. This is wonderful thank you. – Bmo Oct 23 '12 at 18:08
13

This solution is an extension for a Random class.

Usage

class Program
{
    private static Random random = new Random(); 

    static void Main(string[] args)
    {
        random.NextString(10); // "cH*%I\fUWH0"
        random.NextString(10); // "Cw&N%27+EM"
        random.NextString(10); // "0LZ}nEJ}_-"
        random.NextString();   // "kFmeget80LZ}nEJ}_-"
    }
}

Implementation

public static class RandomEx
{
    /// <summary>
    /// Generates random string of printable ASCII symbols of a given length
    /// </summary>
    /// <param name="r">instance of the Random class</param>
    /// <param name="length">length of a random string</param>
    /// <returns>Random string of a given length</returns>
    public static string NextString(this Random r, int length)
    {
        var data = new byte[length];
        for (int i = 0; i < data.Length; i++)
        {
            // All ASCII symbols: printable and non-printable
            // data[i] = (byte)r.Next(0, 128);
            // Only printable ASCII
            data[i] = (byte)r.Next(32, 127);
        }
        var encoding = new ASCIIEncoding();
        return encoding.GetString(data);
    }

    /// <summary>
    /// Generates random string of printable ASCII symbols
    /// with random length of 10 to 20 chars
    /// </summary>
    /// <param name="r">instance of the Random class</param>
    /// <returns>Random string of a random length between 10 and 20 chars</returns>
    public static string NextString(this Random r)
    {
        int length  = r.Next(10, 21);
        return NextString(r, length);
    }
}
oleksii
  • 35,458
  • 16
  • 93
  • 163
12

Yet another version of string generator. Simple, without fancy math and magic digits. But with some magic string which specifies allowed characters.

Update: I made generator static, so it will not return same string when called multiple times. However this code is not thread-safe and is definitely not cryptographically secure.

For password generation System.Security.Cryptography.RNGCryptoServiceProvider should be used.

private Random _random = new Random(Environment.TickCount);

public string RandomString(int length)
{
    string chars = "0123456789abcdefghijklmnopqrstuvwxyz";
    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < length; ++i)
        builder.Append(chars[_random.Next(chars.Length)]);

    return builder.ToString();
}
Community
  • 1
  • 1
Maksym Davydov
  • 150
  • 2
  • 8
10

Here is one more option:

public System.String GetRandomString(System.Int32 length)
{
    System.Byte[] seedBuffer = new System.Byte[4];
    using (var rngCryptoServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider())
    {
        rngCryptoServiceProvider.GetBytes(seedBuffer);
        System.String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        System.Random random = new System.Random(System.BitConverter.ToInt32(seedBuffer, 0));
        return new System.String(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
    }
}
Zygimantas
  • 8,547
  • 7
  • 42
  • 54
7

The best solution is using the random number generator toghether with base64 conversion

public string GenRandString(int length)
{
  byte[] randBuffer = new byte[length];
  RandomNumberGenerator.Create().GetBytes(randBuffer);
  return System.Convert.ToBase64String(randBuffer).Remove(length);
}
Ami Luttwak
  • 171
  • 1
  • 1
5

A LINQ one-liner for good measure (assuming a private static Random Random)...

public static string RandomString(int length)
{
    return new string(Enumerable.Range(0, length).Select(_ => (char)Random.Next('a', 'z')).ToArray());
}
Alex
  • 7,639
  • 3
  • 45
  • 58
4

This is because each new instance of Random is generating the same numbers from being called so fast. Do not keep creating a new instance, just call next() and declare your random class outside of your method.

John T
  • 23,735
  • 11
  • 56
  • 82
3

You should have one class-level Random object initiated once in the constructor and reused on each call (this continues the same sequence of pseudo-random numbers). The parameterless constructor already seeds the generator with Environment.TickCount internally.

Kenan E. K.
  • 13,955
  • 3
  • 43
  • 48
2

Here is my modification of the currently accepted answer, which I believe it's a little faster and shorter:

private static Random random = new Random();

private string RandomString(int size) {
    StringBuilder builder = new StringBuilder(size);
    for (int i = 0; i < size; i++)
        builder.Append((char)random.Next(0x41, 0x5A));
    return builder.ToString();
}

Notice I didn't use all the multiplication, Math.floor(), Convert etc.

EDIT: random.Next(0x41, 0x5A) can be changed to any range of Unicode characters.

quantum
  • 3,672
  • 29
  • 51
  • psst... you actually didn't answer the *problem* the OP had... – Andrew Barber Nov 01 '12 at 02:30
  • @Andrew This actually fix the problem, note that this is also an optimization I made to the accepted answer. – quantum Nov 01 '12 at 02:48
  • Your code does. Your description makes no mention of it, though. As for it being an optimization; I'd want to see some benchmarks before agreeing with that statement; there's stuff going on you are (apparently) not aware of. Like implicit conversions. Plus, you missed potentially the biggest performance boost of all - specifying a starting size for the StringBuilder. (IMHO) – Andrew Barber Nov 01 '12 at 02:52
  • @Andrew I will modify my answer to reflect that, but with generate a uniformly distributed with the method provided by .NET, instead of the custom method involving a multiplication and floor operation, has to be faster. – quantum Nov 01 '12 at 02:55
2

My RandomString() method to generate a random string.

private static readonly Random _rand = new Random();

/// <summary>
/// Generate a random string.
/// </summary>
/// <param name="length">The length of random string. The minimum length is 3.</param>
/// <returns>The random string.</returns>
public string RandomString(int length)
{
    length = Math.Max(length, 3);

    byte[] bytes = new byte[length];
    _rand.NextBytes(bytes);
    return Convert.ToBase64String(bytes).Substring(0, length);
}
AechoLiu
  • 17,522
  • 9
  • 100
  • 118
2

I think may be this is also acceptable and simple.

Guid.NewGuid().ToString() 
wener
  • 7,191
  • 6
  • 54
  • 78
  • GUIDs aren't guaranteed to be random so you shouldn't abuse them as a PRNG. The current implementation on windows is random, but on older versions it was based on MAC address and time. Who knows what future versions will use. – CodesInChaos Oct 29 '13 at 09:26
  • I don't think so.Nowadays, many people use GUID as primary key, and yes, the GUID may conflict, but `2^128` written out is approximately: `34,028,236,692,093,846,346,337,460,743,177,000,000`. Statistically, if you calculated 1000 GUIDs every second, it would still take trillions of years to get a duplicate.BTW, use guid is so simple, I don't think this is a bad idea. – wener Oct 29 '13 at 15:42
  • The point of a GUID is that it's unique, not that it's random. If you used it as a unique ID I wouldn't complain, but you sell it as a random string, which it currently is, but doesn't guarantee to be. (And thanks the the birthday problem you only need about 2^61 values to hit a duplicate not 2^122, so your "trillions of years" are actually only about 75 million years) – CodesInChaos Oct 29 '13 at 15:52
  • This can generate random string, that's all.Although, it can not generate the same sequence. – wener Feb 14 '14 at 04:09
  • It happens to generate a mostly random string (parts of it are not random) in the current implementation. It's not guaranteed to be random, past implementations were not random and future implementations might not be random either. – CodesInChaos Feb 17 '14 at 08:49
2

If you wanted to generate a string of Numbers and Characters for a strong password.

private static Random random = new Random();

private static string CreateTempPass(int size)
        {
            var pass = new StringBuilder();
            for (var i=0; i < size; i++)
            {
                var binary = random.Next(0,2);
                switch (binary)
                {
                    case 0:
                    var ch = (Convert.ToChar(Convert.ToInt32(Math.Floor(26*random.NextDouble() + 65))));
                        pass.Append(ch);
                        break;
                    case 1:
                        var num = random.Next(1, 10);
                        pass.Append(num);
                        break;
                }
            }
            return pass.ToString();
        }
CGsoldier
  • 441
  • 4
  • 4
  • Note that instance members of the Random class are NOT documented as being thread-safe, so if this method is called from multiple threads at the same time (highly likely if you're making a web app, for example) then the behaviour of this code will be undefined. You either need to use a lock on the random or make it per-thread. – Greg Beech Oct 14 '10 at 18:29
  • 1
    @GregBeech really? Again? Bored much? – Jimmy D Dec 30 '11 at 20:37
2

I added the option to choose the length using the Ranvir solution

public static string GenerateRandomString(int length)
    {
        {
            string randomString= string.Empty;

            while (randomString.Length <= length)
            {
                randomString+= Path.GetRandomFileName();
                randomString= randomString.Replace(".", string.Empty);
            }

            return randomString.Substring(0, length);
        }
    }
animuson
  • 53,861
  • 28
  • 137
  • 147
João Miguel
  • 163
  • 1
  • 4
1

I created this method.

It works great.

public static string GeneratePassword(int Lenght, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        Random rd = new Random();

        if (NonAlphaNumericChars > Lenght || Lenght <= 0 || NonAlphaNumericChars < 0)
            throw new ArgumentOutOfRangeException();

            char[] pass = new char[Lenght];
            int[] pos = new int[Lenght];
            int i = 0, j = 0, temp = 0;
            bool flag = false;

            //Random the position values of the pos array for the string Pass
            while (i < Lenght - 1)
            {
                j = 0;
                flag = false;
                temp = rd.Next(0, Lenght);
                for (j = 0; j < Lenght; j++)
                    if (temp == pos[j])
                    {
                        flag = true;
                        j = Lenght;
                    }

                if (!flag)
                {
                    pos[i] = temp;
                    i++;
                }
            }

            //Random the AlphaNumericChars
            for (i = 0; i < Lenght - NonAlphaNumericChars; i++)
                pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];

            //Random the NonAlphaNumericChars
            for (i = Lenght - NonAlphaNumericChars; i < Lenght; i++)
                pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];

            //Set the sorted array values by the pos array for the rigth posistion
            char[] sorted = new char[Lenght];
            for (i = 0; i < Lenght; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }
Hugo
  • 71
  • 2
  • Shows once again that security is hard to test for. While it "works great" it's not secure. Use a a secure PRNG to generate passwords. – CodesInChaos Nov 19 '12 at 10:00
1

And here is another idea based on GUIDs. I've used it for the Visual Studio performance test to generate random string contaning only alphanumeric characters.

public string GenerateRandomString(int stringLength)
{
    Random rnd = new Random();
    Guid guid;
    String randomString = string.Empty;

    int numberOfGuidsRequired = (int)Math.Ceiling((double)stringLength / 32d);
    for (int i = 0; i < numberOfGuidsRequired; i++)
    {
        guid = Guid.NewGuid();
        randomString += guid.ToString().Replace("-", "");
    }

    return randomString.Substring(0, stringLength);
}
Maciej Zaleski
  • 441
  • 6
  • 7
1
public static class StringHelpers
{
    public static readonly Random rnd = new Random();

    public static readonly string EnglishAlphabet = "abcdefghijklmnopqrstuvwxyz";
    public static readonly string RussianAlphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";

    public static unsafe string GenerateRandomUTF8String(int length, string alphabet)
    {
        if (length <= 0)
            return String.Empty;
        if (string.IsNullOrWhiteSpace(alphabet))
            throw new ArgumentNullException("alphabet");

        byte[] randomBytes = rnd.NextBytes(length);

        string s = new string(alphabet[0], length);

        fixed (char* p = s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                *(p + i) = alphabet[randomBytes[i] % alphabet.Length];
            }
        }
        return s;
    }

    public static unsafe string GenerateRandomUTF8String(int length, params UnicodeCategory[] unicodeCategories)
    {
        if (length <= 0)
            return String.Empty;
        if (unicodeCategories == null)
            throw new ArgumentNullException("unicodeCategories");
        if (unicodeCategories.Length == 0)
            return rnd.NextString(length);

        byte[] randomBytes = rnd.NextBytes(length);

        string s = randomBytes.ConvertToString();
        fixed (char* p = s)
        {
            for (int i = 0; i < s.Length; i++)
            {
                while (!unicodeCategories.Contains(char.GetUnicodeCategory(*(p + i))))
                    *(p + i) += (char)*(p + i);
            }
        }
        return s;
    }
}

You also will need this:

public static class RandomExtensions
{
    public static string NextString(this Random rnd, int length)
    {
        if (length <= 0)
            return String.Empty;

        return rnd.NextBytes(length).ConvertToString();
    }

    public static byte[] NextBytes(this Random rnd, int length)
    {
        if (length <= 0)
            return new byte[0];

        byte[] randomBytes = new byte[length];
        rnd.NextBytes(randomBytes);
        return randomBytes;
    }
}

And this:

public static class ByteArrayExtensions
{
    public static string ConvertToString(this byte[] bytes)
    {
        if (bytes.Length <= 0)
            return string.Empty;

        char[] chars = new char[bytes.Length / sizeof(char)];
        Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
}
Konard
  • 2,298
  • 28
  • 21
1

Actually, a good solution is to have a static method for the random number generator that is thread-safe and doesn't use locks.

That way, multiple users accessing your web application at the same time don't get the same random strings.

There are 3 examples here: http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

I'd use the last one:

public static class RandomGen3
{
    private static RNGCryptoServiceProvider _global = 
        new RNGCryptoServiceProvider();
    [ThreadStatic]
    private static Random _local;

    public static int Next()
    {
        Random inst = _local;
        if (inst == null)
        {
            byte[] buffer = new byte[4];
            _global.GetBytes(buffer);
            _local = inst = new Random(
                BitConverter.ToInt32(buffer, 0));
        }
        return inst.Next();
    }
}

Then you can properly eliminate

Random random = new Random();

And just call RandomGen3.Next(), while your method can remain static.

Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
1

For random string generator :

#region CREATE RANDOM STRING WORD
        char[] wrandom = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','V','X','W','Y','Z'};
        Random random = new Random();
        string random_string = "";
        int count = 12; //YOU WILL SPECIFY HOW MANY CHARACTER WILL BE GENERATE
        for (int i = 0; i < count; i++ )
        {
            random_string = random_string + wrandom[random.Next(0, 24)].ToString(); 
        }
        MessageBox.Show(random_string);
        #endregion
Toprak
  • 283
  • 1
  • 4
  • 11
1

Combining the answer by "Pushcode" and the one using the seed for the random generator. I needed it to create a serie of pseudo-readable 'words'.

private int RandomNumber(int min, int max, int seed=0)
{
    Random random = new Random((int)DateTime.Now.Ticks + seed);
    return random.Next(min, max);
}
Devin Burke
  • 13,642
  • 12
  • 55
  • 82
Ideogram
  • 1,265
  • 12
  • 21
  • C# doesn't have default arguments AFAIK. – quantum Nov 01 '12 at 02:31
  • @xiaomao You are not correct. I use them all the time. They are called "Optional Arguments", by the way. – Andrew Barber Nov 01 '12 at 02:32
  • @Andrew OK, that's a new addition, from MSDN: "Visual C# 2010 introduces named and optional arguments". – quantum Nov 01 '12 at 02:46
  • 2
    @xiaomao I would not call over 3 years, and one previous full version to be a "new addition". It was a well established feature by the time this answer was posted in September of last year. – Andrew Barber Nov 01 '12 at 02:48
0

I found this to be more helpfull, since it is an extention, and it allows you to select the source of your code.

static string
    numbers = "0123456789",
    letters = "abcdefghijklmnopqrstvwxyz",
    lettersUp = letters.ToUpper(),
    codeAll = numbers + letters + lettersUp;

static Random m_rand = new Random();

public static string GenerateCode(this int size)
{
    return size.GenerateCode(CodeGeneratorType.All);
}

public static string GenerateCode(this int size, CodeGeneratorType type)
{
    string source;

    if (type == CodeGeneratorType.All)
    {
        source = codeAll;
    }
    else
    {
        StringBuilder sourceBuilder = new StringBuilder();
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Numbers)
            sourceBuilder.Append(numbers);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Letters)
            sourceBuilder.Append(letters);
        if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.LettersUpperCase)
            sourceBuilder.Append(lettersUp);

        source = sourceBuilder.ToString();
    }

    return size.GenerateCode(source);
}

public static string GenerateCode(this int size, string source)
{
    StringBuilder code = new StringBuilder();
    int maxIndex = source.Length-1;
    for (int i = 0; i < size; i++)
    {

        code.Append(source[Convert.ToInt32(Math.Round(m_rand.NextDouble() * maxIndex))]);
    }

    return code.ToString();
}

public enum CodeGeneratorType { Numbers = 1, Letters = 2, LettersUpperCase = 4, All = 16 };

Hope this helps.

WhyMe
  • 535
  • 2
  • 13
0

In my situation, the password must contain:

  • At least one lower case.
  • At least one upper case.
  • At least one decimal.
  • At least one special character.

Here is my code:

    private string CreatePassword(int len)
    {
        string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "!@#$%^&*()_+" };
        RNGCryptoServiceProvider rndGen = new RNGCryptoServiceProvider();

        byte[] random = new byte[len];
        int[] selected = new int[len];

        do
        {
            rndGen.GetNonZeroBytes(random);

            for (int i = 0; i < random.Length; i++)
            {
                selected[i] = random[i] % 4;
            }
        } 
        while(selected.Distinct().Count() != 4);

        rndGen.GetNonZeroBytes(random);

        string res = "";

        for(int i = 0; i<len; i++)
        {
            res += valid[selected[i]][random[i] % valid[selected[i]].Length];
        }
        return res;
    }
Jules
  • 1,423
  • 13
  • 22
0

Hello
you can use WordGenerator or LoremIpsumGenerator from MMLib.RapidPrototyping nuget package.

using MMLib.RapidPrototyping.Generators;
public void WordGeneratorExample()
{
   WordGenerator generator = new WordGenerator();
   var randomWord = generator.Next();

   Console.WriteLine(randomWord);
} 

Nuget site
Codeplex project site

Mino
  • 305
  • 2
  • 12
0

If you have access to an Intel Secure Key compatible CPU, you can generate real random numbers and strings using these libraries: https://github.com/JebteK/RdRand and https://www.rdrand.com/

Just download the latest version from here, include Jebtek.RdRand and add a using statement for it. Then, all you need to do is this:

bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
string key = RdRandom.GenerateKey(10); //Generate 10 random characters

Plus, you also get these additional capabilities:

string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int

If you don't have a compatible CPU to execute the code on, just use the RESTful services at rdrand.com. With the RdRandom wrapper library included in your project, you would just need to do this (you get 1000 free calls when you signup):

string ret = Randomizer.GenerateKey(<length>, "<key>");

You can also generate random byte arrays and unsigned integers as follows:

uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
JebaDaHut
  • 541
  • 5
  • 11
0

And, another version: I've use this method for generating random pseudo stock symbols in testing:

Random rand = new Random();
Func<char> randChar = () => (char)rand.Next(65, 91); // upper case ascii codes
Func<int,string> randStr = null;
    randStr = (x) => (x>0) ? randStr(--x)+randChar() : ""; // recursive

Usage:

string str4 = randStr(4);// generates a random 4 char string
string strx = randStr(rand.next(1,5)); // random string between 1-4 chars in length

You can redefine the randChar function for use with an "allowed" array of chars by position instead of ascii code:

char[] allowedchars = {'A','B','C','1','2','3'};
Func<char> randChar = () => allowedchars[rand.Next(0, allowedchars.Length-1)];
Gordon Bell
  • 13,337
  • 3
  • 45
  • 64
cramroop
  • 248
  • 3
  • 6
0

Another sample (tested in vs2013):

    Random R = new Random();
    public static string GetRandomString(int Length)
    {
        char[] ArrRandomChar = new char[Length];
        for (int i = 0; i < Length; i++)
            ArrRandomChar[i] = (char)('a' + R.Next(0, 26));
        return new string(ArrRandomChar);
    }

    string D = GetRandomString(12);

Implemented by myself.

Amin Ghaderi
  • 1,006
  • 13
  • 22
0

This is my solution:

private string RandomString(int length)
{
    char[] symbols = { 
                            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'                             
                        };

    Stack<byte> bytes = new Stack<byte>();
    string output = string.Empty;

    for (int i = 0; i < length; i++)
    {
        if (bytes.Count == 0)
        {
            bytes = new Stack<byte>(Guid.NewGuid().ToByteArray());
        }
        byte pop = bytes.Pop();
        output += symbols[(int)pop % symbols.Length];
    }
    return output;
}

// get 1st random string 
string Rand1 = RandomString(4);

// get 2nd random string 
string Rand2 = RandomString(4);

// create full rand string
string docNum = Rand1 + "-" + Rand2;
Konard
  • 2,298
  • 28
  • 21
ADM-IT
  • 3,719
  • 1
  • 25
  • 26