Hansen Derrick
Hansen Derrick

Reputation: 151

How to verify a password to have at least one uppercase, lowercase and number in C?

What should i do to make it keep looping until it have at least one uppercase, lowercase and number ?

I'm stuck, really stuck...

char password[100][15];
i=1;
     printf("Password [3..10]: ");
        gets(password[i]);
        while (strlen(password[i])>10 || strlen(password[i])<3 || ) {   
        do{
        printf("  Password must contain at least 1 uppercase, 1 lowercase, and 1 number\nPassword [3..10]: ");
        gets(password[i]);
        } while (strlen(password[i])>10 || strlen(password[i])<3 );

Upvotes: 4

Views: 5212

Answers (5)

user2742371
user2742371

Reputation:

Use this regular expression:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$

It says that you must have at least one lowercase character, one uppercase character and at least one number PLUS it is less typing than the ctype method.

Example:

#include <regex.h>

int main (int argc, char *argv[])
{
    regex_t regex;
    int regexResult = regcomp(&regex, "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$", 0);
    regexResult = regexec(&regex, passwordVariableHere, 0, NULL, 0);

    if (!regex)
    {
        // Match
    }
}

Upvotes: 2

Charlie Burns
Charlie Burns

Reputation: 7056

This should work:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int is_legal(char *p) {
  int number = 0, lower = 0, upper = 0, length = 0;
  for( ; *p; p++) {
      number += isdigit(*p);   
      lower  += islower(*p);     
      upper  += isupper(*p);
      length++;
  }
  return number > 0 && lower > 0 && upper > 0  && length > 3 && length < 10;
}

char *my_gets(char *buf, int bufsize, FILE *file) {
    if(fgets(buf, bufsize, file) == 0) {
        return 0;
    }
    int n = strlen(buf);
    if(buf[n-1] == '\n') buf[n-1] = 0;
    return buf;
}

int get_password(char *buf, int bufsize, FILE *file) {
    printf("Password [3..10]: ");
    if(my_gets(buf, bufsize, file) == 0) {
        return -1;
    }
    while(is_legal(buf) == 0) {
       printf("  Password must contain at least 1 uppercase, 1 lowercase, and 1    umber\nPassword [3..10]: ");
       if(my_gets(buf, bufsize, file) == 0) {
           return -1;
       }
    }
    return 0;
}

int main(void) {
    char password[100][15];
    int i = 0;
    if(get_password(password[i], sizeof(password[i]), stdin) != 0) {
        fprintf(stderr, "Error getting password\n");
        exit(1);
   }
   return 0;
}

Upvotes: 10

ShinTakezou
ShinTakezou

Reputation: 9681

I don't get very well why you are using an array of 15-chars long passwords, but I suppose your criteria refers to just one of those password and not to the others: you want to check that a password has requirements to be considered a "good" password; this is my understanding. Then...

The function gets is rather unsafe. Avoid using it.

The idea is to ask for a password, check it and loop if it does not fit your criteria. There's not a single way to do it of course.

// include files for I/O funcs
#include <stdio.h>

for(;;)
{
   printf("insert pwd: ");
   gets(buffer); // argh I've said: don't use this
   if ( !pass_criteria(buffer) ) {
       printf("criteria are ....\n");
   } else break;
}

Then pass_criteria could be something like

// include files for strlen and is* funcs
#include <ctype.h>
#include <string.h>

int pass_criteria(const char *buf)
{
    int upcount, lowcount, numcount;

    if (strlen(buf) < minimum_pass_len ||
        strlen(buf) > max_pass_len) return 0; // 0 being false

    for (int i = 0; i < strlen(buf); ++i) {
       if (isdigit(buf[i]) numcount++;
       if (isupper(buf[i]) upcount++;
       if (islower(buf[i]) lowcount++;
    }
    return numcount > 0 && upcount > 0 && lowcount > 0;
}

It's easy to change criteria, e.g. if you want at least 2 number (digit), put numcount > 1 and so on.

Instead of gets

Gets is dangerous for buffer overflow. Try using e.g. fgets like this:

   fgets(buffer, buffer_size, stdin);

where buffer_size is the size of your buffer (15 in your case, but avoid using a literal constant; prefer a proper #define or use sizeof, e.g. sizeof (password[0]). Note also that fgets does not discard final newline.

Upvotes: 0

Maxik
Maxik

Reputation: 1

Maybe it's an easy way to check the characters position in the ASCII table. You can check all characters as numbers between 65 and 90 for uppsercase characters and the same for lowercase.

For a number you could use atoi() function from standard c library.

Or another possibility is using functions from ctype.h: islower(), isupper() or isdigit().

Upvotes: 0

Look at ctype.h header. Examine every character of password until all conditions (upper, lower, digit) are met. If you reach end of password string and any of conditions are unsatisfied, password is wrong.

Upvotes: 0

Related Questions