只有在设置断点时才创建唯一密钥,否则将复制密钥
本文关键字:密钥 复制 唯一 创建 设置 断点 | 更新日期: 2023-09-27 18:21:12
所以,我相信对此有一个简单的解释,但我使用C#才几个月,所以我还有很多东西要学。
我只是在开发一个小应用程序,它可以生成一组独特的密钥,只是一些基本的构建技能。
我遇到了这个问题,如果我在所有迭代中在keyList.Add(sb.ToString());
和F5处设置断点,我会得到一个键列表,并且所有键都有唯一的值,但如果我删除断点并只运行解决方案,它只会重复相同的键。
有人能解释一下为什么会发生这种事吗?这与Random()
或我放置StreamWriter
有关吗?
public class KeyCreator
{
public static void alphaList()
{
string lowerAlpha = "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";
string upperAlpha = "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";
SortedList<string, string> alphaList = new SortedList<string, string>();
string[] splitListLower = lowerAlpha.Split(',');
string[] splitListUpper = upperAlpha.Split(',');
for (int i = 0; i < splitListLower.Length; i++)
{
alphaList.Add(splitListLower[i], splitListUpper[i]);
}
numberGen(alphaList);
}
public static void numberGen(SortedList<string, string> alphaList)
{
List<string> keyList = new List<string>();
for (int b = 0; b < 20; b++)
{
int max = alphaList.Count;
StringBuilder sb = new StringBuilder();
Random rnd = new Random();
for (int i = 0; i < 4; i++)
{
int upperLower = rnd.Next(0, 10);
if (upperLower < 5)
{
for (int a = 0; a < 4; a++)
{
int lowerUpper = rnd.Next(0, 10);
if (lowerUpper < 4)
{
int index = rnd.Next(0, max);
sb.Append(alphaList.Keys[index]);
}
else if (lowerUpper > 3 && lowerUpper < 7)
{
int index = rnd.Next(0, max);
sb.Append(alphaList.Values[index]);
}
else if (lowerUpper > 6)
{
int rand = rnd.Next(0, 9);
sb.Append(rand);
}
}
}
else if (upperLower > 4)
{
for (int a = 0; a < 4; a++)
{
int lowerUpper = rnd.Next(0, 10);
if (lowerUpper < 4)
{
int index = rnd.Next(0, max);
sb.Append(alphaList.Keys[index]);
}
else if (lowerUpper > 3 && lowerUpper < 7)
{
int index = rnd.Next(0, max);
sb.Append(alphaList.Values[index]);
}
else if (lowerUpper > 6)
{
int rand = rnd.Next(0, 9);
sb.Append(rand);
}
}
}
if (i < 3)
{
sb.Append("-");
}
}
keyList.Add(sb.ToString());
}
using (StreamWriter writer = new StreamWriter(@"C:'temp'keys.txt"))
{
foreach (string key in keyList)
{
writer.WriteLine(key);
}
}
}
}
问题是:
public static void numberGen(SortedList<string, string> alphaList)
{
List<string> keyList = new List<string>();
for (int b = 0; b < 20; b++)
{
int max = alphaList.Count;
StringBuilder sb = new StringBuilder();
Random rnd = new Random(); //<-- This line is the problem
默认情况下,Random
以当前日期/时间为种子。由于DateTime
的准确性并不是很高,所以您正在一次又一次地创建相同的随机数。当您中断调试器时,它会起作用,因为您暂停的时间足够长,DateTime
可以进行足够的更改,为Random
创建一个新种子。
解决方案是这样做:
[ThreadStatic]
static Random rnd = new Random();
public static void numberGen(SortedList<string, string> alphaList)
{
//This if is required because it can be null on subsequent threads.
if (rnd == null) rnd = new Random();
List<string> keyList = new List<string>();
for (int b = 0; b < 20; b++)
{
int max = alphaList.Count;
StringBuilder sb = new StringBuilder();
将创建的对象移动到循环之外并使用相同的实例。
此外,正如Scott Chamberlain在评论中指出的那样,Random
不是线程安全的,静态方法应该是线程安全的。因此,我添加了[ThreadStatic]
属性,以避免在每次Next
调用周围都需要lock
。不这样做并从多个线程调用它可能会导致Random
状态损坏并返回全零。