Random generating similar numbers.

  • (2 Pages)
  • +
  • 1
  • 2

26 Replies - 1728 Views - Last Post: 10 August 2016 - 06:54 AM Rate Topic: -----

#1 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Random generating similar numbers.

Posted 06 August 2016 - 01:49 AM

I have been working on making a random password generator. Everything is all working as I have coded it to, but one thing that I have noticed is that if you include numbers (you can choose what char sets to include using check boxes) I get a lot of 5's in the passwords. Some other numbers hardly ever come up like 3's. It makes me wonder how random it actually is? I want to know if it's just the way C#'s random works, or if I have coded something incorrectly.

Here is 5 randomly generated passwords from my program (using only numbers as the passwords).

52535657
53495755
56485151
48524855
55565649

There are 18 5's there and 2 3's and 2's.

I can't say I have seen the same pattern with the letters, but obviously there are a lot more letters to choose from.

Here is the code that runs when I click the "Generate" button:

 private void cmdGenerate_Click(object sender, EventArgs e)
        {
            intPassLenght = Int32.Parse(comLenght.Text);
            
            if (!chkLower.Checked && !chkUpper.Checked && !chkNumbers.Checked && !chkSymbols.Checked)
            {
                chkLower.Checked = true;
            }

            txtPassword.Text = "";

            Random random = new Random();
            
            while (txtPassword.Text.Length < intPassLenght)
            { 
                int rndArray = random.Next(0, 4);

                    switch (rndArray)
                    {
                    case 0:
                        if (chkLower.Checked)
                        {
                            int rand = random.Next(0, 26);
                            txtPassword.Text += strLowerCase[rand];
                        }
                        break;

                    case 1:
                        if (chkUpper.Checked)
                        { 
                            int rand = random.Next(0, 26);
                            txtPassword.Text += strUpperCase[rand];
                        }
                        break;
                    case 2:
                        if (chkNumbers.Checked)
                        {
                            int rand = random.Next(0, 10);
                            txtPassword.Text += intNumbers[rand];
                        }
                        break;
                    case 3:
                        if (chkSymbols.Checked)
                        {
                            int rand = random.Next(0, 21);
                            txtPassword.Text += strSymbols[rand];
                        }
                        break;
                }
            }
        }



Thanks for your time.

James

Is This A Good Question/Topic? 0
  • +

Replies To: Random generating similar numbers.

#2 andrewsw  Icon User is online

  • say what now
  • member icon

Reputation: 6409
  • View blog
  • Posts: 25,903
  • Joined: 12-December 12

Re: Random generating similar numbers.

Posted 06 August 2016 - 02:44 AM

Five cannot be considered a sample. 500 or 5000 would be more reasonable, and a good exercise for you to build some test code.

You should only create one instance of Random(), at class level, you don't need a new instance every time a button is clicked. (This is often a cause of repeated values, if the code were to execute very fast so that more than one Random is created in the same instance of time. This isn't the case here, unless your name is Flash.)
Was This Post Helpful? 2
  • +
  • -

#3 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Re: Random generating similar numbers.

Posted 06 August 2016 - 03:55 AM

I just did 5 results for the sake of this thread, but I have tested it myself a fair bit (not to the scale of 500 I would admit) and it seems to always do the same sort of thing, lots of 5's.

I have moved the Random() outside of the generate button now so I will have a test of that, although on trying a few I'm still seeing the same sort of pattern. Do you think it might be worth generating 500 passwords and then doing some code to count the amount of 1's, 2's, 3's etc and see how the numbers stack up then?

Thanks

James
Was This Post Helpful? 0
  • +
  • -

#4 SixOfEleven  Icon User is offline

  • Planeswalker
  • member icon

Reputation: 1055
  • View blog
  • Posts: 6,643
  • Joined: 18-October 08

Re: Random generating similar numbers.

Posted 06 August 2016 - 04:13 AM

When I'm working with Random I typically create a static member for it in the class that would be shared by all instances of that class. It helps prevent what andrewsw was mentioning. That said there is no way to truly generate random numbers. The best that can be done is pseudo-random numbers and based on the algorithm used there is the potential for clumps of numbers. These clumps can also be caused by the seed used for generating the numbers. They can also be caused by the range, as you've noticed. Most games do not use the random number generator (RNG) that is shipped with the language of choice. They typically implement their own (RNG). It would be a good exercise to search for some different RNG algorithms, implement them and compare the results between the different RNGs to see what kind of distribution you get.

It would be a good idea to work with some larger data sets to see what kind of distribution you are getting for the individual digits. Start with 500, but you may wand to go higher, as 500 is still a relatively small sample.
Was This Post Helpful? 2
  • +
  • -

#5 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Re: Random generating similar numbers.

Posted 06 August 2016 - 04:26 AM

I'll have a look into RNG algorithms then, sounds interesting.

I'll also try it on a much larger data set and see what happens. It's not the biggest problem in the world as my original goal was to build a password generator which I have done and it works. I was just curious about the numbers seeming similar as it could affect future projects. You guys have pointed me in the right direction tho!

Thanks

James.
Was This Post Helpful? 0
  • +
  • -

#6 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Random generating similar numbers.

Posted 06 August 2016 - 04:58 AM

According to this test all digits appear with pretty much the same frequency. Both using a single RNG or creating new one each time (as long as the seed is different). Ideone runs the code with Mono, but I doubt you'd get a different result with .NET - feel free to try it though.
Was This Post Helpful? 0
  • +
  • -

#7 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5925
  • View blog
  • Posts: 20,255
  • Joined: 05-May 12

Re: Random generating similar numbers.

Posted 06 August 2016 - 09:24 AM

View PostJames7285, on 06 August 2016 - 07:26 AM, said:

I'll have a look into RNG algorithms then, sounds interesting.


And if you decide to implement your own RNG be sure to follow Eric Lippert's advice regarding bias ... which happens to be implemented in the C# Random class.
Was This Post Helpful? 1
  • +
  • -

#8 SixOfEleven  Icon User is offline

  • Planeswalker
  • member icon

Reputation: 1055
  • View blog
  • Posts: 6,643
  • Joined: 18-October 08

Re: Random generating similar numbers.

Posted 06 August 2016 - 10:18 AM

Very nice article.
Was This Post Helpful? 0
  • +
  • -

#9 Michael26  Icon User is offline

  • Futurama: Insert funny joke here
  • member icon

Reputation: 414
  • View blog
  • Posts: 1,664
  • Joined: 08-April 09

Re: Random generating similar numbers.

Posted 07 August 2016 - 10:04 AM

The Danger of Na´vetÚ
Was This Post Helpful? 0
  • +
  • -

#10 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Re: Random generating similar numbers.

Posted 08 August 2016 - 05:06 AM

Very interesting articals, thanks guys.

Without changing anything in my program, I wrote some code for it to generate 50,000 eight digit random passwords and then got it to count the amount of times each number came back.

Posted Image

As you can see, it MASSIVELY favours 5's and to some extent 4's. Everything else seems to have come out fine.

I'm not sure why it would do this, but maybe I need to have a look into implementing a different RND code.
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5925
  • View blog
  • Posts: 20,255
  • Joined: 05-May 12

Re: Random generating similar numbers.

Posted 08 August 2016 - 05:28 AM

Can you show us your sampling program? Are you still creating an instance of the Random class on each call?
Was This Post Helpful? 0
  • +
  • -

#12 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Re: Random generating similar numbers.

Posted 08 August 2016 - 06:13 AM

The random class is called for outside of the generate button so it's only called for once.

I don't know if I have done this the best way and it could be a factor in the numbers, but I have 4 check boxes where the user can pick if they want uppercase, lowercase, numbers and symbols. When you generate a new code it picks a random number between 1 and 4 (1 being uppercase, 2 being lowercase etc) then it checks to see if the box is checked, if it is then it picks a random letter/digit from that array, if not it picks again. It does this until the password box reaches the number of digits specified.

Here is the code:

private void cmdGenerate_Click(object sender, EventArgs e)
        {
            //Checks how many characters the user wants in the password.
            intPassLenght = Int32.Parse(comLenght.Text);
            
            //Checks to make sure that all of the checkboxes aren't unticked.
            if (!chkLower.Checked && !chkUpper.Checked && !chkNumbers.Checked && !chkSymbols.Checked)
            {
                chkLower.Checked = true;
            }

            //Blanks the previous password.
            txtPassword.Text = "";

            
            //Randomly picks an array from which to choose the next character, if that array is unticked it tries again until the password is complete.
            while (txtPassword.Text.Length < intPassLenght)
            { 
                int rndArray = random.Next(0, 4);

                    switch (rndArray)
                    {
                    case 0:
                        if (chkLower.Checked)
                        {
                            int rand = random.Next(0, 26);
                            txtPassword.Text += strLowerCase[rand];
                        }
                        break;

                    case 1:
                        if (chkUpper.Checked)
                        { 
                            int rand = random.Next(0, 26);
                            txtPassword.Text += strUpperCase[rand];
                        }
                        break;
                    case 2:
                        if (chkNumbers.Checked)
                        {
                            int rand = random.Next(0, 10);
                            txtPassword.Text += intNumbers[rand];
                        }
                        break;
                    case 3:
                        if (chkSymbols.Checked)
                        {
                            int rand = random.Next(0, 21);
                            txtPassword.Text += strSymbols[rand];
                        }
                        break;
                }
            }


This is the code outside of the generate button which sets up the variables and arrays...
namespace Random_Password_Generator
{
    public partial class frmMain : Form
    {
        public int intPassLenght;
        public char[] strLowerCase = new char[] {'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'};
        public char[] strUpperCase = new char[] {'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'};
        public char[] strSymbols = new char[] {'!', '#', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', '~', ':', ';', '<', '=', '>', '?', '@', '['};
        public int[] intNumbers = new int[] {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
        Random random = new Random();

This post has been edited by James7285: 08 August 2016 - 06:15 AM

Was This Post Helpful? 0
  • +
  • -

#13 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5925
  • View blog
  • Posts: 20,255
  • Joined: 05-May 12

Re: Random generating similar numbers.

Posted 08 August 2016 - 06:30 AM

Okay... but where is the code that you use to collect your statistics? I can't quite believe that you actually sat there and clicked your "Generate" button exactly 320000 times. Also, I find it odd that the numbers 0, 1, 2, 3, 6, 7, 8, and 9 all had counts of exactly 20000, unless its an artifact of your charting software where it rounds up to tick marks.

- Ants
Was This Post Helpful? 0
  • +
  • -

#14 James7285  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 92
  • Joined: 24-October 02

Re: Random generating similar numbers.

Posted 08 August 2016 - 06:37 AM

Ah, sorry! My mistake. I left that out as I thought you were just talking about the main program code.

Plus I'm pretty sure the code I wrote for collecting the counts is probably an awful way of doing it, but it seemed to work.

I put all of the generate code above into a timer and then added this at the bottom:

string test = txtPassword.Text;

            var count = test.Count(x => x == '0');
                intZeros += count;
                label2.Text = intZeros.ToString();

            var count2 = test.Count(x => x == '1');
                intOnes += count2;
                label3.Text = intOnes.ToString();

            var count3 = test.Count(x => x == '2');
                intTwos += count3;
                label4.Text = intTwos.ToString();

            var count4 = test.Count(x => x == '3');
                intThrees += count4;
                label5.Text = intThrees.ToString();

            var count5 = test.Count(x => x == '4');
                intFours += count5;
                label6.Text = intFours.ToString();

            var count6 = test.Count(x => x == '5');
                intFives += count6;
                label7.Text = intFives.ToString();

            var count7 = test.Count(x => x == '6');
                intSixes += count7;
                label8.Text = intSixes.ToString();

            var count8 = test.Count(x => x == '7');
                intSevens += count8;
                label9.Text = intSevens.ToString();

            var count9 = test.Count(x => x == '8');
                intEights += count9;
                label10.Text = intEights.ToString();

            var count10 = test.Count(x => x == '9');
                intNines += count10;
                label11.Text = intNines.ToString();


They didn't all come to exactly 20000, I think it's just the rubbish excel bar graph. Here are the exact results:

0 20111
1 20153
2 20047
3 20188
4 59974
5 180006
6 19848
7 19755
8 20000
9 19918
Was This Post Helpful? 0
  • +
  • -

#15 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Random generating similar numbers.

Posted 08 August 2016 - 06:54 AM

public int[] intNumbers = new int[] {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};


You're creating an int array and putting chars into it. This will cause those chars to be converted to int using their Unicode codepoint (which is 48 for '0'. 49 for '1' etc.). So your array actually looks like this:

public int[] intNumbers = new int[] {49, 50, 51, 52, 53, 54, 55, 56, 57, 48};


So that should explain why the number 5 appears so often (and why 4 also appears more often than the others). It should also explain why you never get an odd number of digits and why sometimes the password length will be one greater than the desired one.
Was This Post Helpful? 2
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2