Is using a GUID a valid way to generate a random s

2019-01-28 16:18发布

问题:

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?

回答1:

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



回答2:

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.



回答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);
}


回答4:

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



回答5:

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.



回答6:

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.



回答7:

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



标签: c# .net random