基于this question我想知道使用GUID生成随机字符串和数字是否有任何缺陷?
因此,例如,如果我想要一个随机字符串和32个或更少字符的数字,我可以使用以下C#代码:
string s = Guid.NewGuid().ToString().Replace("-", "");
如果长度需要小于32,我会截断字符串,如果需要更长,我会将多个GUID一起添加。
这种方法有哪些缺陷?
在我写完之后,我意识到一个缺陷就是它只会有字母a到f所以我会修改这个问题:
这是一个真正随机的6个字符和10个数字的序列吗?
答案 0 :(得分:18)
GUID不保证随机性,它保证了唯一性。如果您想要随机性,请使用Random生成字符串。
答案 1 :(得分:12)
它实际上并不是随机的,而是(相对)唯一的。如果你真的想要随机性,我建议使用类似System.Random中值的哈希值。
Here's指向.NET“System.Random”的MSDN文档的链接,以及Hashing package的相同链接。
答案 2 :(得分:3)
正如其他答案所解释的那样,GUID
只保证唯一性,而不是随机性。
如果您需要的是唯一性,那么您问题中的代码就可以了,尽管您可以使用Guid.NewGuid().ToString("N")
而不是显式替换连字符。
如果你确实需要一个随机字符串,那么尝试这样的事情:
// 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);
}
答案 3 :(得分:2)
没有。例如,标准的GUID生成算法包括当前时间和执行生成的计算机的MAC地址。
答案 4 :(得分:1)
如前所述,GUID被设计为唯一且不随机。生成"random" string(即满足某些随机性统计要求)的更好且更简单的方法是使用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();
}
如果您需要“更安全”的随机数,您可能需要查看RNGCryptoServiceProvider
。但正如约翰·冯·诺伊曼said已经{/ 3>
任何考虑产生随机数字的算术方法的人当然都处于犯罪状态。
答案 5 :(得分:0)
如前所述,GUID旨在生成Unique,然后保持几乎静态。由于所有随机生成都只是伪随机的(你会在生成几千个整数值后开始看到模式),所以只使用标准的Random()类是理想的。每次构造一个新对象时,它都将使用当前系统时间对其进行播种。这将保证它最接近随机。你永远不应该使用静态的东西来种子随机方法。
答案 6 :(得分:-2)
由于Guid独特的原因,解决方案还可以。