Password

I have a assignment due in a few days and I am having some difficulties.

Here is the assignment:
//Create a random 10 character password with the first character being a upper case letter.
//The remaining characters are random selections of Upper case letters, lower case letters, 9 digits and/or special characters (found only on the top row of your keyboard).
//Please exclude 0 and O's from being used. After generating the password, display the password to the user and ask them to enter the password until it is entered correctly.
//Once the password is entered correctly please display the message "Sign On now successful!".

This is what I've got so far:

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

//Create a random 10 character password with the first character being a upper case letter.
//The remaining characters are random selections of Upper case letters, lower case letters, 9 digits and/or special characters (found only on the top row of your keyboard).
//Please exclude 0 and O's from being used. After generating the password, display the password to the user and ask them to enter the password until it is entered correctly.
//Once the password is entered correctly please display the message "Sign On now successful!".

using namespace std;

static const char alphanum[] =
"123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNPQRSTUVWXYZ"
"abcdefghijklmnpqrstuvwxyz";//excluding (0,O,o)

int stringLength = sizeof(alphanum) - 1;

char genRandom() // Random string generator function.
{

return alphanum[rand() % stringLength];
}

int main()
{
srand(time(0));
for(int z=0; z < 10; z++)
{
cout << genRandom();

}
cout << "\nPlease enter the password provided. " << endl;

cout << "Thank you, acess granted! " << endl;
return 0;

}

I want the user to have to confirm what the random password generated by the computer, once they do they have access. I also need the first character to be capitalized per the requirements of the assignment.

Any help would be appreciated.

@caseypowell1987

Please study how this program was made, and ways you could make it your own. Do not just copy & paste and present it as your work, as the teacher would easily know the difference, especially when asking questions on how you did it. Learn from it, and you'll become a better programmer..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

//Create a random 10 character password with the first character being a upper case letter.
//The remaining characters are random selections of Upper case letters, lower case letters, 9 digits and/or special characters (found only on the top row of your keyboard).
//Please exclude 0 and O's from being used. After generating the password, display the password to the user and ask them to enter the password until it is entered correctly.
//Once the password is entered correctly please display the message "Sign On now successful!".

using namespace std;

static const string alphanum[4] = {"123456789","!@#$%^&*","ABCDEFGHIJKLMNPQRSTUVWXYZ","abcdefghijklmnpqrstuvwxyz"};//excluding (0,O,o)

int stringLength = sizeof(alphanum) - 1;

char genRandom(int row, int len) // Random string generator function.
{

	return alphanum[row][rand()% len];
}

int main()
{
	srand((unsigned)time(0));
	int row, len;
	string Password="", PW;
	char PW_Add;
	for(int z=0; z < 10; z++)
	{
		if(z==0)// First time thru. Only get a Capital letter
		{
			row = 2;
			len = 25;
		}
		else
		{
			row = rand()%4;// Pick one of the four strings
			if(row == 0)
				len = 9; // String 0 is 9 long
			else if(row == 1)
				len = 8; // String 1 is 8 long
			else
				len = 25; // String 2 and 3 are 25 long. 26 letters of alphbet, minus the O or o
		}
		PW_Add = genRandom(row, len);
		Password+=PW_Add;
	}
	cout << "Random password is '" << Password << "'" << endl;
	do
	{
		cout << endl << "Please re-enter the password provided. " << endl;
		cin >> PW;
	}while (PW != Password);
	cout << "Sign On now successful!" << endl << endl;
	cout << "Enter any letter to close program.." << endl << endl;
	cin >> PW_Add;
	return 0;
}
Last edited on
comments within program, shout if anything's unclear:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <string>
#include <random>
#include <chrono>
#include <algorithm>
#include <iterator>

static const std::vector<char> alphanum {'1','2','3','4','5','6','7','8','9',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z',
    'a','b','c','d','e','f','g','h','i','j','k','l','m','n','p','q','r','s','t','u','v','w','x','y','z'};
static  const std::vector<char> upperCase{alphanum.begin()+9, alphanum.begin()+34};

constexpr auto passwordSize = 10;

int main()
{
    auto seed = std::chrono::system_clock::now().time_since_epoch().count();//seed
    std::default_random_engine dre(seed);//engine
    std::uniform_int_distribution<int> d_all(0, alphanum.size()-1);//distribution for all characters
    std::uniform_int_distribution<int> d_upper(0, upperCase.size()-1);//distribution for uppercase only

    std::string password(passwordSize, ' ');//string to hold password
    auto it = upperCase.cbegin();
    std::advance(it, d_upper(dre));//advance iterator by random number b/w 0 and size of uppercase
    password[0] = *it;//choose the value of iterator after random advance as password[0]

    std::generate(password.begin()+1, password.end(), [&]{ return alphanum[d_all(dre)];});
    //http://en.cppreference.com/w/cpp/algorithm/generate
    //generate the rest of the characters for the password string

    std::cout << password << "\n";

    bool match = false;
    while (!match)
    {
        std::cout << "Now enter the password yourself: \n";
        std::string enteredPassword;
        getline(std::cin, enteredPassword);
        if (enteredPassword == password)
        {
            std::cout << "Thank you, acces granted \n";
            match = true;
        }
        else
        {
            std::cout << "Wrong entry, try again \n";
        }
    }

}



@whitenite1,

Your password selection has a bias in it. Because the strings are longer, you are less likely to select a particular letter than a particular number.

Ignoring the first character, probabilities for the rest include:
probability of 'a' is (1/4)*(1/25)
probability of '9' is (1/4)*(1/9)
These differ by more than a factor of 2.
@gunnerfunner

Thanks for the input, I am trying to gather ideas of how to make the program better that I've started. When I tried to run your program it wouldn't work.. :(

I am using the Bloodshed Dev c++ compiler.
@ whitenite1

Thank you! I will study it well, it did exactly what I needed, can you DM me and talk me through your program?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;

const string CHOICE = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789!@#$%^&*";

//======================================================================

char randchar( int len ) { return CHOICE[ rand() % len ]; }

//======================================================================

int main()
{
   const int PWLEN = 10;
   srand( time( 0 ) );
   string password = "", PW;
   int lenmax = CHOICE.size();

   // Generate first character
   password += randchar( 25 );

   // Generate remaining characters
   for( int i = 2; i <= PWLEN; i++ ) password += randchar( lenmax );

   cout << "Random password is: " << password << '\n';
   do
   {
      cout << "Please re-enter the password provided: \n";
      cin >> PW;
   } while ( PW != password );

   cout << "Sign On now successful!\n";
}

I am using the Bloodshed Dev c++ compiler.

this IDE uses an out-of-date compiler. As an alternative suggest Code::Blocks that is much more up to date - http://www.codeblocks.org/
@lastchance

Your password selection has a bias in it. Because the strings are longer, you are less likely to select a particular letter than a particular number.

I don't see how. There is equal chance of any number in the rand()%4 coming up. Then when a number is chosen, any random number equal to the string length can be gotten. And if one letter, number or symbol is chosen more, well, I guess that's why it's called 'random'.
Hello @whitenite1

(Forgetting the first digit, which is an unbiased choice amongst the upper-case letters), for your approach of choosing set first, then different numbers within that set:

- probability of selecting 'a' is the probability of selecting lower case (1/4) TIMES probability of selecting 'a' amongst those lower-case letters (1/25); the probability of selecting 'a' for any particular character by your approach is therefore 1/100;

- probability of selecting '9' is the probability of selecting digits (1/4) TIMES probability of selecting '9' amongst those digits (1/9); the probability of selecting '9' for any particular character is therefore 1/36;

Certainly it is "random" in that you don't know the outcome, like any other probability distribution. However, this doesn't produce a UNIFORM distribution. Your code would select a '9' nearly three times as often as an 'a'. That is definitely biased in favour of '9'.

It's slightly more biased in favour of each particular punctuation symbol.


By contrast, each character in @GunnerFunner's code has an equal, unbiased probability of 1/59, whilst in mine they have equal unbiased probabilities of 1/67; (I used a slightly larger set to choose from). I suspect @GunnerFunner's random-number generator is also a bit better behaved than the rand() that the rest of us used.
Last edited on
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <string>
#include <time.h>
#include <iostream>

int main()
{
    std::string numbers = "123456789";
    std::string specials = "!@#$%^&*";
    std::string capitals = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
    std::string lowers = "abcdefghijklmnpqrstuvwxyz";
    
    std::string altogether = numbers + specials + capitals + lowers;
    std::string password = "";
    
    srand (time(NULL));
    password += capitals[rand() % capitals.length()];
    for(int i= 0; i < 9; ++i)
    {
        password += altogether[rand() % altogether.length()];
    }
    std::cout << "Password: " << password << '\n';
    
    return 0;
}


Just combine the lot as required and if you run it through a loop the results look pretty random to me. ( True randomness doesn't matter all that much because in a serious password system not involving other independent authentication a simple countermeasure is a time lockout after a couple of unsuccessful tries notwithstanding all the other bells and whistles possible. )

Password: TPL5CjLi1T
Password: I62j8ci6*i
Password: ZQh5k77SWt
Password: V^NC27QAga
Password: Jy@tb8yz1c
Password: GDGr##Y6wi
Password: DVkbEE4#^A
Password: YnWU5tu2A1
Password: SCT$u&uh5D
Password: V&XLCcIhEJ
Password: Rdpvu9h2Jl
Password: N2UwIpV@N2
Password: Af3gB@%Ejm
Password: NYsFyFBVbc
Password: LcPFthj8Qw
Password: Rzv^UlXEjk
Password: P8WlHVaXsT
Password: F$e1TE1Lxe
Password: Ig#^TggR8v
Password: I9K6t$!Q7w
Program ended with exit code: 0


PS srand is used because Bloodshed probably can't handle the more sophisticated and accurate <random> functionality @gunnerfunner that has so ably referred to. The prime minister of Singapore is the only person on the face of the planet who still uses that outdated and unsupported piece of crap. Actually it's worse, he uses Dev C :(
Last edited on
each character in ... mine ... have equal unbiased probabilities of 1/67;

lastchance: I think the probability for the first character in your program would also be 1/25 since:
1
2
// Generate first character
   password += randchar( 25 );

Upon re-reading the OP realized that I did miss out the special characters though
probability for the first character in your program would also be 1/25


Yes, that's the same for all code examples. It was characters 2 - 10 in the password that I was referring to. I deliberately put the upper-case characters first in the combined string
const string CHOICE = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789!@#$%^&*";
so that I could do this for the first password character, but still use it for the rest.

Probabilities for all the rest would be 1/(length of string) = 1/67.

Last edited on
Topic archived. No new replies allowed.