C#逐步生成唯一的安全随机字符串
我想随机生成唯一和安全的字符串,我想随着时间的推移这样做。我想为我的使用选择尽可能短的长度(足够大,以便随机尝试很有可能失败)。我也希望这个过程是快速的。使用以下代码并测试其唯一性,重复出现的时间比我预期的要早。我不确定是否有什么问题 注意:使用池生成号码安全吗 p.p.S:我不喜欢在字母表上加“-”和“-”。它值得移除吗C#逐步生成唯一的安全随机字符串,c#,random,unique,C#,Random,Unique,我想随机生成唯一和安全的字符串,我想随着时间的推移这样做。我想为我的使用选择尽可能短的长度(足够大,以便随机尝试很有可能失败)。我也希望这个过程是快速的。使用以下代码并测试其唯一性,重复出现的时间比我预期的要早。我不确定是否有什么问题 注意:使用池生成号码安全吗 p.p.S:我不喜欢在字母表上加“-”和“-”。它值得移除吗 string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; s
string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
string Random(int length,string alphabet)
{
StringBuilder result = new StringBuilder();
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < length; i++)
{
byte[] buffer = new byte[sizeof(uint)];
rng.GetBytes(buffer);
uint num = BitConverter.ToUInt32(buffer, 0);
result.Append(alphabet[(int)(num % (uint)alphabet.Length)]);
}
}
return result.ToString();
}
string Alphabet=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyzo123456789-”;
随机字符串(整数长度,字符串字母表)
{
StringBuilder结果=新建StringBuilder();
使用(RNGCryptoServiceProvider rng=new RNGCryptoServiceProvider())
{
for(int i=0;i
通常,在字母表中,每个字符有6位“信息”(共64个字符)。因此,长度=10的字符串有60位信息。对于after sqrt(2^60),即2^30,应该有0.5的碰撞可能性(50%)。2^30相当大,但如果字符数较低,则冲突将发生得更早
请注意,您的代码中可能存在优化(预先分配StringBuilder的“正确”长度),但存在一个bug:
public const string BaseAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
public static string Random(int length, string alphabet = BaseAlphabet)
{
StringBuilder result = new StringBuilder(length);
uint maxValue = (uint)((((ulong)uint.MaxValue) + 1) / (uint)alphabet.Length * (uint)alphabet.Length);
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < length; i++)
{
uint num;
do
{
byte[] buffer = new byte[sizeof(uint)];
rng.GetBytes(buffer);
num = BitConverter.ToUInt32(buffer, 0);
}
while (num >= maxValue);
result.Append(alphabet[(int)(num % (uint)alphabet.Length)]);
}
}
return result.ToString();
}
public const string BaseAlphabet=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789-”;
公共静态字符串随机(整数长度,字符串字母表=基本字母表)
{
StringBuilder结果=新StringBuilder(长度);
uint maxValue=(uint)(((ulong)uint.maxValue)+1)/(uint)alphabet.Length*(uint)alphabet.Length);
使用(RNGCryptoServiceProvider rng=new RNGCryptoServiceProvider())
{
for(int i=0;i=maxValue);
结果。追加(字母[(int)(num%(uint)alphabet.Length)];
}
}
返回result.ToString();
}
在您编写的代码中,某些字符可能比其他字符更可能出现。这是因为if(uint.MaxValue+1
)(rng生成的整个可能数字范围)不能完全被字母表整除。长度
则字母表末尾的字符比开头的字符可能性小。可能重复的字符可能有助于对代码进行拼写检查。看一看,代码根本不会运行。重复出现的时间比我预期的要早。
您预期它们是什么时候出现的?什么时候发生的?这感觉像是XY问题-。你为什么要这样做?“短”和“安全”是两件通常不能很好地结合在一起的事情。任何足够短的东西也可以很容易地被粗暴地强迫和/或预测。更重要的是,你不想让东西因为名字难以猜测而变得安全,你想让它们因为根本无法访问而变得安全。如果您使用16个随机字节,并将它们转换为32个字符的十六进制字符串,然后使用它,您将拥有128位的随机性。这当然足以防止碰撞。在这方面,Guid.NewGuid()
也是如此,尽管这在加密方面并不安全。