Jac*_*cob 2 .net c# asp.net random
我有一个ASP.NET应用程序,它依赖于Random类来生成伪随机字符串.它使用以下代码(这是Google为应用程序SSO提供的更大范围的示例代码的一部分):
public static class SamlUtility
{
private static Random random = new Random();
private static char[] charMapping = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' };
public static string CreateId()
{
byte[] bytes = new byte[20]; // 160 bits
random.NextBytes(bytes);
char[] chars = new char[40];
for (int i = 0; i < bytes.Length; i++)
{
int left = (bytes[i] >> 4) & 0x0f;
int right = bytes[i] & 0x0f;
chars[i * 2] = charMapping[left];
chars[i * 2 + 1] = charMapping[right];
}
return new string(chars);
}
}
Run Code Online (Sandbox Code Playgroud)
这通常很有效,但有时会开始生成一串'a'.从我从调试中可以看出,Random只是停止返回随机数,而是反复填充具有相同值的字节.我通过使用GUID来修补此问题,但我很好奇原始代码中发生了什么.我假设某种形式的熵耗尽,但我在文档中找不到任何参考.此外,每次发生这种情况时,执行iisreset都会恢复正确的行为.
任何有关出错的建议都将不胜感激.
该Random班是不是线程安全的.
如果同时在多个线程上的同一实例上生成随机数,则其内部状态将被破坏,并且它将开始返回零.
您需要创建Random实例[ThreadStatic]以确保每个实例不被多个线程共享.
请注意,[ThreadStatic]字段的初始化程序只运行一次,因此您需要检查是否null每次使用该字段并在必要时进行初始化.
在种子中包含线程ID和当前时间以防止种子冲突也是一个好主意.
顺便提一下,注意Random班级不安全; 考虑使用该RNGCryptoServiceProvider课程