2

Possible Duplicate:
How Random is System.Guid.NewGuid()?

Based on this question I would like to know if using a GUID to generate a random string of characters and numbers has any flaws in it?

So, for example, if I wanted a random string of characters and numbers of 32 or fewer characters I could use the following C# code:

string s = Guid.NewGuid().ToString().Replace("-", "");

If the length needed to be shorter than 32 I would truncate the string and if it needed to be longer I would add multiple GUID's together.

What are the flaws in this approach?

After I wrote this I realized that one flaw would be that it would only ever have the letters a through f so I will modify the question:

Is this a truly random sequence of 6 characters and 10 digits?

Community
  • 1
  • 1
Guy
  • 65,082
  • 97
  • 254
  • 325
  • 2
    Can you describe for what _purpose_ you want random characters? – Eric Lippert May 27 '09 at 20:04
  • I was thinking of using it for an email verification token. i.e. A user registers on a site and a confirmation email is sent to the user with a 32 character token as a param to the verification URL. – Guy May 28 '09 at 17:58

7 Answers7

18

A GUID doesn't make guarantees about randomness, it makes guarantees around uniqueness. If you want randomness, use Random to generate a string.

Michael
  • 54,279
  • 5
  • 125
  • 144
  • 2
    The random class itself only generates pseudo-random numbers. If you want something more random you will need to use something like RNGCryptoServiceProvider- http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx – RichardOD May 27 '09 at 20:18
12

It's not actually intended to be random, but instead to be (relatively) unique. If you really want randomness, I recommend using something like a hash of a value from System.Random.

Here's a link to the MSDN documentation for the .NET "System.Random", as well as the same for their Hashing package.

TML
  • 12,813
  • 3
  • 38
  • 45
3

As the other answers have explained, a GUID only guarantees uniqueness, not randomness.

If uniqueness is all that you need then the code in your question is fine, although you could just use Guid.NewGuid().ToString("N") rather than explicitly replacing the hyphens.

If you do actually need a random string, then try something like this:

// use RNGCryptoServiceProvider instead of Random if you need extra security
private readonly Random _rng = new Random();

public string GetRandomString(int length)
{
    const string allowedChars =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    char[] buffer = new char[length];

    for (int i = 0; i < length; i++)
    {
        buffer[i] = allowedChars[_rng.Next(allowedChars.Length)];
    }

    return new string(buffer);
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
2

No. For example, standard GUID-generating algorithms include things like the current time and the MAC address of the computer doing the generation.

Aric TenEyck
  • 8,002
  • 1
  • 34
  • 48
1

As already stated GUIDs are designed to be unique and not to be random. A better and rather simple way to generate a "random" string (i.e. meeting certain statistical requirements for randomness) would be to use Random:

/// <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();
}

If you need "more secure" random numbers you might want to check out RNGCryptoServiceProvider. But as already John von Neumann said:

Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
0

As stated before, the GUID is designed to be generated Unique and then to stay almost static. Since all random generation is only pseudo-random (you'll start seeing patterns after generating a few thousand integer values) it's ideal to just use the standard Random() class. Every time it constructs a new object, it'll seed it with the current system time. This will guarantee it to be the closest to random. You should never use something static to seed Random methods.

-2

Due to the reason that Guid is unique the solution is ok.

crauscher
  • 6,528
  • 14
  • 59
  • 85
  • 1
    The OP is looking for a random string, not one that is simply unique. Since GUIDs only make guarantees about uniqueness, not randomness, the solution is not ok. – William Brendel May 27 '09 at 19:46
  • 1
    Unique doesn't mean unguessable - although I'm not aware of any work on 'guessing the next UUID in sequence', it's not a designed-in property of the UUID algorithm as I understand it, so I would encourage the use of an actual (P?)RNG instead. – TML May 27 '09 at 19:46
  • 2
    Uniqueness does not guarantee Randomness. Ex. (staticcount++) could be considered unique for each returned value, but is most definitely not random {1,2,3,4,5...} – Joseph May 27 '09 at 19:47
  • 1
    The OP also mentions truncating the GUID string to the required length - if they do that, it is far less likely to be unique. – Daniel Earwicker May 27 '09 at 19:53