views:

820

answers:

7

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?

+16  A: 

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

Michael
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
+9  A: 

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
A: 

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

crauscher
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
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
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
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
Right, my fault.
crauscher
+2  A: 

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
+1  A: 

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.

0xA3
A: 

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.

+1  A: 

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