1

可能重复:
随机数生成器仅生成一个随机数

我下面的代码正在这样做,我不知道为什么:

如果我的 toEmailAddresses 数组包含 2 个电子邮件地址,uniqueID[0]并且uniqueID[1]将返回从Util.CreateRandomPassword(16)方法调用生成的相同值。

如果我单步执行代码,那么两者都uniqueID[0]uniqueID[1]包含应有的不同值。但是如果我像往常一样运行代码,出于某种原因,相同的值会分配给我的uniqueID数组: uniqueID[0]并且uniqueID[1]将包含相同的值。

我什至放入string tempRandomPassword = null然后将其分配给从CreateRandomPassword方法返回的值,但这也不起作用。

我究竟做错了什么?

//toEmailAddresses.Count array will have two e-mail addresses in it.

string[] uniqueID = new string[2];

for (int i = 0; i < toEmailAddresses.Count(); i++)
{
   string tempRandomPassword = null;
   tempRandomPassword = Util.CreateRandomPassword(16);

   uniqueID[i] = tempRandomPassword;
}


        public static string CreateRandomPassword(int passwordLength)
        {
            //http://madskristensen.net/post/Generate-random-password-in-C.aspx

            string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
            char[] chars = new char[passwordLength];
            Random rd = new Random();

            for (int i = 0; i < passwordLength; i++)
            {
                chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
            }

            return new string(chars);
        }
4

4 回答 4

1

这是因为你的方法使用

 Random rd = new Random();

这个 Random 的本地实例将使用时钟自动初始化,但是当两个实例创建得太近(及时)时,它们将使用相同的种子并产生相同的随机序列。

只要您不从多个线程调用它,您就可以使用静态字段作为简单的修复:

    private static Random _rd = new Random();

    public static string CreateRandomPassword(int passwordLength)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        char[] chars = new char[passwordLength];
        // Random rd = new Random();

        ...
    }
于 2013-01-04T20:32:09.067 回答
1

您每次都创建一个新的 Random 对象,并且由于它使用时间作为默认种子,因此您将获得相同的种子,从而获得相同的数字。

使其成为类的一个字段,并且只创建一次。

这就是为什么当你顺便通过它时它起作用的原因。额外的时间允许种子改变并返回不同的结果。

于 2013-01-04T20:32:25.263 回答
1

您将Random在每次调用时使用默认种子创建一个新实例。如果种子相同,它将产生相同的数字序列。存储实例并将其用于所有调用。

于 2013-01-04T20:32:42.447 回答
-1

在循环中使用线程睡眠

private void button3_Click(object sender, EventArgs e)
        {
            string[] uniqueID = new string[2];
            string[] toEmailAddresses = new string[2];
            toEmailAddresses[0] = "a@1.com";
            toEmailAddresses[1] = "b@1.com";

            for (int i = 0; i < toEmailAddresses.Count(); i++)
            {
                uniqueID[i] = CreateRandomPassword(16);
                System.Threading.Thread.Sleep(10);               
            }

            for (int i = 0; i < uniqueID.Count(); i++)
                MessageBox.Show(i.ToString() + " : " + uniqueID[i]);
        }
于 2013-01-04T20:48:53.547 回答