HW Assignment

Can anyone help with this type of assignment? The only library I can use is <iostream>.

For this assignment, you are to implement a program that can be used for rating user passwords.

The criteria that should be used for rating passwords are: • Has a length of at least 8 characters • Contains at least 1 uppercase letter • Contains at least 1 lowercase letter • Contains at least 1 digit (0 through 9) • Contains at least 1 non-alphabetic and non-digit character

The rating for a password is determined by the (maximum) number of the above criteria are satisfied by the password, and are as follows
Rating # of Criteria Satisfied Best 5 Good 4 Weak 3 Poor 2 Unacceptabble 1

Using the above information about ratings and the criteria used to determine ratings, you are to implement an application that allows a user to evaluate a sequence of passwords.

The program should begin by asking the user if there is a password to be evaluated. Each time the user responds in the affirmative by inputting a “y” (uppercase or lowercase) the program should then prompt the user to input a password. Next, the program should evaluate that password, and output the rating for that password based on the criteria specified earlier.

This process of asking the user if there is a password to be evaluated, and evaluating a password should continue until the user responds in the negative by inputting an “n” (uppercase of lowercase).

Once all of the passwords have been processed, the program should then output the number of passwords rated at each level. That is, the program should output the number of passwords rated Best, the number rated Good, and so on.
The actual rating of a password should be performed by the function PWRating(), having the following prototype int PWRating(char pw[]);
This function should return the rating of the password passed to it in the parameter pw.
All of the string data used in the program should be processed as C-stings.
Last edited on
with only iostream you will have to do it with c-strings and for loops to check each condition. It will be annoying, but easy enough.
Hint: get a copy of the ascii table (extended, 0-255) and have it on hand so you can check ranges of letters quickly to see if you meet the rules.
there are more efficient tricks you can pull, but given the 'do it with both hands and 1 foot tied behind your back' rules, this code isn't worth the trouble to think those out unless you are just feeling it for fun.

Hint2: make functions and built PWRating from those, don't do it all in one. Make one for 'has lower' and one for 'has upper' and one for 'has digit' and so on...

Hint3: arrange the output of your above has functions to make the final score easy to compute, like 1 or 0 and add them all up (3 is good, 5 is excellent or whatever)

Last edited on
thanks for those hints. how do you make a function from which I can build the PWRating function? I understand these concepts individually, I'm just not certain how to tie them together in a program.
Well you could start with
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstring>
#include <cctype>

int my_strlen(const char *s) {
  return strlen(s);
}
int my_isupper(char c) {
  return isupper(c)
}

int PWRating(char pw[]) {
  if ( my_strlen(pw) < 8 ) {
    return 0;  // your rating
  }
  // other tests
}


When that works, you can go about replacing the contents of all the my_ functions with your own code, rather than relying on the existing library code.
do you know how I can write a for loop to check through each character of the array of characters for password?
1
2
3
4
5
6
7
8
9
10
// return count of how many characters in cstr are equal to the given letter
int count( const char cstr[], char letter )
{
    if( cstr == nullptr ) return 0 ;

    int cnt = 0 ;
    for( ; *cstr != 0 ; ++cstr ) // for each char in cstr, till the terminating null char
        if( *cstr == letter ) ++cnt ;
    return cnt ;
}
I also need to write a for loop for checking if each character is an uppercase, lower case, number, and special character. I have the 'for' part down (I think), I just can't figure out how to actually run the test.

#include <iostream>

using namespace std;

int main()
{
char pw[50]; //ARRAY OF CHARS
int criteriasatisfied;
int rating;
char enterpassword; // checks if the user wants to enter a password

//ask the user if s/he wants to enter a password to check validity

cout << "Do you want to enter a password? (Y/N): ";
cin >> enterpassword;

if (enterpassword == 'y')
cout << "Please enter a password:\n " <<
"Password requirements:\n"
"Minimum length of at least 8 characters\n"
"Contains at least 1 uppercase letter\n"
"Contains at least 1 lowercase letter\n"
"Contains at least 1 number (0 through 9)\n"
"Contains at least 1 non-alphanumeric character" << endl;

cin >> pw; //each element is a char
}

int PWRating(char pw[]) = (); {
for (int i = 0; i > pw; i++)
}

//count the number of characters in the string (stored in element of array)

int strlen(char s[])
{
for (int i = 0; s[i] != '\0'; i++)
;
return i;

//check each character for upper case

for (int i = 0; s[i] != '\0'; i++)
;
iscapital(a[i]);

//check each character for lower case
for (int i = 0; s[i] != '\0'; i++)
;
//check each character for a number
for (int i = 0; s[i] != '\0'; i++)
;
//check each character for a non-alphanumeric special character
for (int i = 0; s[i] != '\0'; i++)
;
This reference to isupper() might be of use.

http://www.cplusplus.com/reference/cctype/isupper/?kw=isupper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

const char upper[]   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
           lower[]   = "abcdefghijklmnopqrstuvwxyz",
           number[]  = "0123456789",
           special[] = "!\"œ$%^&*()_+{}:@~|<>?-=[]'#\\,./ª`";
const char rating[6][13] = { "?", "Unacceptable", "Poor", "Weak", "Good", "Best" };

bool lap( const char* a, const char* b )
{
   if ( !*a ) return false;
   for ( auto bb = (char*)b; *bb; bb++ ) if ( *a == *bb ) return true;
   return lap( a + 1, b );
}

int length( const char* a ) { return *a ? 1 + length( a + 1 ) : 0; }

int PWRating( const char* pw ) { return ( length( pw ) >= 8 ) + lap( pw, upper ) + lap( pw, lower ) + lap( pw, number ) + lap( pw, special ); }

int main()
{
   for ( auto pw : {"last","lastchance","lastChance","lastChance9","lastChance9?" } ) std::cout << pw << " " << rating[PWRating(pw)] << '\n';
}
do this once in main, or in a function that can pass the table back out.

unsigned char table[256] = {10};
int dx;
for(dx = '0'; dx <= '9'; dx++) table[dx] = 0; //digits
for(dx = 'A; dx <= 'Z'; dx++) table[dx] = 1; //upper
for(dx = 'a; dx <= 'z'; dx++) table[dx] = 2; //lower
//then you have to define symbol. symbol could mean 'everything else except 0 null char' or it could mean "shift+digit on keyboard" or whatever. set symbols to 3 however you choose to define them -- that may be an ascii range or a couple of ranges or letter by letter (ugg).

now you have all you need really.
bool allpassed[4] = {false};
for(all the characters)
{
allpassed[0] |= (table[input[currentindex]]==0);
allpassed[1] |= (table[input[currentindex]]==1);
allpassed[2] |= (table[input[currentindex]]==2);
allpassed[3] |= (table[input[currentindex]]==3); //etc
}
if(allpassed[0] && allpassed[1] && allpassed[2] && allpassed[3]) //passed, combine with length or other checks and score it
Last edited on
I can only include <iostream>, no other libraries.

Also, what is "Const char"? is it a data type?
Did you mean this, @jonnin?
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 <iostream>

const char upper[]   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
           lower[]   = "abcdefghijklmnopqrstuvwxyz",
           number[]  = "0123456789",
           special[] = "!\"o$%^&*()_+{}:@~|<>?-=[]'#\\,./`";
const char rating[6][13] = { "?", "Unacceptable", "Poor", "Weak", "Good", "Best" };

int PWRating( const char* pw )
{
   int A[256]{};
   for ( ; *pw; pw++ ) A[*pw]++;
   int u = 0, l = 0, n = 0, s = 0;
   for ( char c : upper   ) u += A[c];
   for ( char c : lower   ) l += A[c];
   for ( char c : number  ) n += A[c];
   for ( char c : special ) s += A[c];
   return ( u + l + n + s >= 8 ) + ( u > 0 ) + ( l > 0 ) + ( n > 0 ) + ( s > 0 );
}

int main()
{
   for ( auto pw : {"last","lastchance","lastChance","lastChance9","lastChance9?" } ) std::cout << pw << "  " << rating[PWRating(pw)] << '\n';
}

last  Unacceptable
lastchance  Poor
lastChance  Weak
lastChance9  Good
lastChance9?  Best
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
#include <iostream>

int main()
{
    char password[]{"^6Ca$-m%"};
    char sample{0};
    int score[5]{0};
    
    std::cout << "Password: " << password << '\n';
    int pw_length = sizeof(password)/sizeof(char) - 1;
    std::cout << "Password length: " << pw_length << '\n';
    
    for( int i = 0; i < pw_length; i++ )
    {
        sample = password[i];
        
        if(pw_length < 8)
        {
            std::cout << "Password too short\n";
            break;
        }
        else
            score[0] = 1;
        
        if( isupper(sample) )
            score[1] = 1;
        else if( islower(sample) )
            score[2] = 1;
        else if ( isdigit(sample) )
            score[3] = 1;
        else
            score[4] = 1;
    }
    
    int total_score = 0;
    for(int i = 0; i < sizeof(score)/sizeof(int); i++)
    {
        std::cout << "Score[" << i << "]: " << score[i] << '\n';
        total_score += score[i];
    }
    std::cout << "Total score: " << total_score << '\n';
    
    return 0;
}


Pretty rough but now all you need is to build the password input logic and some sort of enum stuff to convert the score to words.
Surely, isupper(), islower(), isdigit() are all part of the (disallowed) library <cctype> (which has probably been pulled in by <iostream>).

Also, pw_length is fixed by the length of the password buffer fixed at compile time: the user would never get the chance to try different password lengths.
Please enter password: 1
Password: 1
Password length: 1
Password too short
Score[0]: 0
Score[1]: 0
Score[2]: 0
Score[3]: 0
Score[4]: 0
Total score: 0
Rating: INVALID
Please enter password: 12345678
Password: 12345678
Password length: 8
Score[0]: 1
Score[1]: 0
Score[2]: 0
Score[3]: 1
Score[4]: 0
Total score: 2
Rating: Poor
Please enter password: 1we3qtyuuuu
Password: 1we3qtyuuuu
Password length: 11
Score[0]: 1
Score[1]: 0
Score[2]: 1
Score[3]: 1
Score[4]: 0
Total score: 3
Rating: Weak
Please enter password: a#Def567-+?
Password: a#Def567-+?
Password length: 11
Score[0]: 1
Score[1]: 1
Score[2]: 1
Score[3]: 1
Score[4]: 1
Total score: 5
Rating: Best
Please enter password: 56rkm.>~
Password: 56rkm.>~
Password length: 8
Score[0]: 1
Score[1]: 0
Score[2]: 1
Score[3]: 1
Score[4]: 1
Total score: 4
Rating: Good
Please enter password: 


Thank you for your interest in my work.

The output looks good to me when I run my complete program, which meets the spec.

So what if <iostream> 'pulls it in', if in fact that is what happens. It might even be hidden part of my system - one of the great mysteries of life.

My only 'regret' is in my previous comment where I guessed enums are useful. But the fix for that is trivial and simpler as my complete program shows.
1
2
3
4
5
6
7
8
            if( sample >= 'A' and sample <= 'Z')//isupper(sample) )
                score[1] = 1;
            else if( sample >= 'a' and sample <= 'z' )// islower(sample) )
                score[2] = 1;
            else if ( sample >= '0' and sample <= '9')// isdigit(sample) )
                score[3] = 1;
            else
                score[4] = 1;
Last edited on
Did you mean this, @jonnin?

similar. I was saying only one bigger lookup table, and avoiding any searching of it, just straight letter in / type of it comes out out table of the whole extended ascii. but same idea, just a little more compacted.
Topic archived. No new replies allowed.