Random does not work correctly in the C# loop [duplicate]

This question is already answered here: The initial value of Random() in C# (1 answer) Closed 11 months ago.

There is a code that reads the dimensions of the image, after which it must create three random keys ( the values of which do not exceed the number of pixels of the image vertically and horizontally, that is, select random pixels of the image), add them to the list, and then write them to a file.

        private void OkButton_Click(object sender, EventArgs e)
    {
        if (OpenPictureBox.Image != null & textMessage.Text != null)

        {
            SavePictureBox.Image = OpenPictureBox.Image;
            SavePictureBox.SizeMode = PictureBoxSizeMode.Zoom;
            string text = textMessage.Text;
            byte[] bittext = Encoding.UTF8.GetBytes(text); //преобразовали текст в байты
            BitArray bits = new BitArray(bittext); //преобразовали байты в биты                       
            Bitmap container = new Bitmap(OpenPictureBox.Image);
            Bitmap fullcontainer = new Bitmap(container);
            int n = container.Height;
            int m = container.Width;
            int r = 3; //количество раз, которое сообщение будет записываться в контейнер


            //СОЗДАНИЕ КЛЮЧА
            List<List<List<int>>> keys = new List<List<List<int>>>(); //создаем пустой массив для ключей
            StringBuilder keysstr = new StringBuilder();

            for (int i = 0; i < r; i++)
            {
                List<List<int>> key = new List<List<int>>(); //пустой массив для каждого из трех кючей
                for (int j = 0; j < bits.Length; j++)
                {
                    List<int> k = new List<int>();
                    Random rnd = new Random();
                    int k1 = rnd.Next(10, m - 10);
                    int k2 = rnd.Next(10, n - 10);
                    k.Add(k1);
                    k.Add(k2);
                    keysstr.Append(Convert.ToString(k1));
                    keysstr.Append(" ");
                    keysstr.Append(Convert.ToString(k2));
                    if (j < bits.Length - 1)
                    {
                        keysstr.Append(",");
                    }
                    key.Add(k);
                }
                //key.Sort();
                keys.Add(key);
                if (i < r - 1)
                {
                    keysstr.Append(";");
                }
            }
            //записываем ключи в файл
            string fileName = "keys.txt";
            FileStream aFile = new FileStream(fileName, FileMode.OpenOrCreate);
            StreamWriter sw = new StreamWriter(aFile);
            aFile.Seek(0, SeekOrigin.End);
            sw.WriteLine(keysstr.ToString());

            sw.WriteLine(bits.Length.ToString());
            sw.WriteLine(m.ToString());
            sw.WriteLine(n.ToString());

            sw.Close();
   }

The problem is that in the end, the entire list consists of the first pixel obtained in this code snippet

                    List<int> k = new List<int>();
                    Random rnd = new Random();
                    int k1 = rnd.Next(10, m - 10); //значение пикселя по горизонтали
                    int k2 = rnd.Next(10, n - 10); //значение пикселя по вертикали
                    k.Add(k1);
                    k.Add(k2);

I tried it reset the variables k1 and k2 at the end of the loop, but it doesn't change anything. At the same time, a piece of code that generates a key copied to a separately created file and based on randomly taken values from the head (and not based on the image) works correctly...

Author: fraimz, 2020-03-15

1 answers

You need to read the C documentation# Random.

In short, when creating new Random(), conditionally, this object already contains all the random numbers generated from the "grain". In the constructor without parameters, the "grain" is the current time.

Your loop is executed in almost an instant, and the "grain" (i.e. time) is the same. This means that the random numbers are also the same.

To solve the problem, you need to move the creation of the object Random outside of the loop and use this one object in the loop.

In general, it is considered good practice to create an object Random once per program execution (for example, to make it static). This will eliminate the possibility of repeating random numbers if you call the OkButton_Click method several times very quickly.

 2
Author: ANU CHEEKI BREEKI, 2020-03-15 11:46:06