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

2019-01-28 15:34发布

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?

标签: c# .net random
7条回答
欢心
2楼-- · 2019-01-28 16:08

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.

查看更多
forever°为你锁心
3楼-- · 2019-01-28 16:18

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

查看更多
你好瞎i
4楼-- · 2019-01-28 16:18

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.

查看更多
来,给爷笑一个
5楼-- · 2019-01-28 16:22

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.

查看更多
聊天终结者
6楼-- · 2019-01-28 16:22

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

查看更多
ゆ 、 Hurt°
7楼-- · 2019-01-28 16:25

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);
}
查看更多
登录 后发表回答