我有一个实用程序函数,我希望将其作为URL查询字符串的一部分。我需要确保它始终是唯一的
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz0123456789";
var random = new Random();
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
如果说我在14中传入了长度,则生成类似
的哈希值 YS5bwVTjwEBhFp
sNi6EfU5rUxI2Z
sQKhqhklw22vb2
如果我使用一年的时间谈论20,000次使用,那么说它应该总是唯一的吗?
再次
答案 0 :(得分:3)
确保唯一性的一种方法是保存生成的值并在使用之前进行验证,这是过去从未使用过的。另一种方法是预先生成大量值,将它们保存在表中,然后选择下一个可用值。这个主题的变化是确保唯一性的唯一方法 如果参数没有意义(没有语义)。
另一种方法是增加意义。而不是YS5bwVTjwEBhFp
,sNi6EfU5rUxI2Z
等使用0
,1
等(来自数据库的增量值)。当然,您可以对此进行编码,例如。通过加密,转换为对用户没有意义的值,因此用户仍然可以看到sNi6EfU5rUxI2Z
,但这是base64编码的加密值1
或类似的东西。
最后,对于所有实际用途,仅使用加密随机字符串(即。RNGCryptoServiceProvider.GetBytes
)应该绰绰有余。不保证独特,但极不可能发生冲突。
答案 1 :(得分:0)
不确定你的System.Random是否那么棒,但你可以结合更好的Cryptopgraphy方案。你的10个角色和40个更好的角色......
这是Linqpad
示例:您的h0UcVayzu2
生成
另一个更好的人生成LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG
组合后是50个字符
h0UcVayzu2LyR7SUYZ-ZPll36wzGI5kMPamKtyXV_rN0Ax6iZG
代码:
void Main()
{
var x = RandomString(10);
x.Dump();
var y = Example.GenerateIdentifier(40);
y.Dump();
var z = x + y;
z.Dump();
}
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz0123456789";
var random = new Random();
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
public class Example {
static readonly char[] AvailableCharacters = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
};
internal static string GenerateIdentifier(int length) {
char[] identifier = new char[length];
byte[] randomData = new byte[length];
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) {
rng.GetBytes(randomData);
}
for (int idx = 0; idx < identifier.Length; idx++) {
int pos = randomData[idx] % AvailableCharacters.Length;
identifier[idx] = AvailableCharacters[pos];
}
return new string(identifier);
}
}