How efficient is my code that determines if a password is valid or not? [closed]












-2















The requirements are that the password has to include an upper-case letter, an number, and the "$" sign. Everything works (except for when the user inputs a space for some reason, so help on that would be appreciated), but idk how efficient my code is. I'm new to C so, any advice? (Also is there any way to set a "maximum length" for my password other than just setting it to something really high or forcing the user to follow the limit?)



int main(void){

int maxlength = 15;
char password[maxlength];
int index = 0;
int x = 0;
int y = 0;
int z = 0;

printf("Enter Password: "); //Mike$4
scanf(" %s", password);

do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked

if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}

if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){

if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
return 0;}


Basically every time a requirement is hit I just noted it by incrementing x, y, or z, and if by the end of the password, they all have at least 1, then it's a good password.



Thanks!



I'm asking if there's a better way to code this, because my next CS course in school will mark based on efficiency as well so I wanna make sure I know what makes a C code efficient or not. And of course, how to deal with the space in the password.










share|improve this question















closed as too broad by Rob K, Sᴀᴍ Onᴇᴌᴀ, user3386109, usr2564301, Retired Ninja Jan 1 at 0:07


Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.



















  • For what it's worth, you might want to check out the latest NIST guidance about password policies.

    – Daniel Pryden
    Dec 31 '18 at 21:12






  • 2





    It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

    – user3386109
    Dec 31 '18 at 21:15






  • 1





    How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

    – Robert Harvey
    Dec 31 '18 at 21:25













  • When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

    – Jonathan Leffler
    Dec 31 '18 at 21:37













  • For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

    – David C. Rankin
    Dec 31 '18 at 21:49


















-2















The requirements are that the password has to include an upper-case letter, an number, and the "$" sign. Everything works (except for when the user inputs a space for some reason, so help on that would be appreciated), but idk how efficient my code is. I'm new to C so, any advice? (Also is there any way to set a "maximum length" for my password other than just setting it to something really high or forcing the user to follow the limit?)



int main(void){

int maxlength = 15;
char password[maxlength];
int index = 0;
int x = 0;
int y = 0;
int z = 0;

printf("Enter Password: "); //Mike$4
scanf(" %s", password);

do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked

if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}

if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){

if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
return 0;}


Basically every time a requirement is hit I just noted it by incrementing x, y, or z, and if by the end of the password, they all have at least 1, then it's a good password.



Thanks!



I'm asking if there's a better way to code this, because my next CS course in school will mark based on efficiency as well so I wanna make sure I know what makes a C code efficient or not. And of course, how to deal with the space in the password.










share|improve this question















closed as too broad by Rob K, Sᴀᴍ Onᴇᴌᴀ, user3386109, usr2564301, Retired Ninja Jan 1 at 0:07


Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.



















  • For what it's worth, you might want to check out the latest NIST guidance about password policies.

    – Daniel Pryden
    Dec 31 '18 at 21:12






  • 2





    It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

    – user3386109
    Dec 31 '18 at 21:15






  • 1





    How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

    – Robert Harvey
    Dec 31 '18 at 21:25













  • When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

    – Jonathan Leffler
    Dec 31 '18 at 21:37













  • For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

    – David C. Rankin
    Dec 31 '18 at 21:49
















-2












-2








-2








The requirements are that the password has to include an upper-case letter, an number, and the "$" sign. Everything works (except for when the user inputs a space for some reason, so help on that would be appreciated), but idk how efficient my code is. I'm new to C so, any advice? (Also is there any way to set a "maximum length" for my password other than just setting it to something really high or forcing the user to follow the limit?)



int main(void){

int maxlength = 15;
char password[maxlength];
int index = 0;
int x = 0;
int y = 0;
int z = 0;

printf("Enter Password: "); //Mike$4
scanf(" %s", password);

do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked

if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}

if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){

if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
return 0;}


Basically every time a requirement is hit I just noted it by incrementing x, y, or z, and if by the end of the password, they all have at least 1, then it's a good password.



Thanks!



I'm asking if there's a better way to code this, because my next CS course in school will mark based on efficiency as well so I wanna make sure I know what makes a C code efficient or not. And of course, how to deal with the space in the password.










share|improve this question
















The requirements are that the password has to include an upper-case letter, an number, and the "$" sign. Everything works (except for when the user inputs a space for some reason, so help on that would be appreciated), but idk how efficient my code is. I'm new to C so, any advice? (Also is there any way to set a "maximum length" for my password other than just setting it to something really high or forcing the user to follow the limit?)



int main(void){

int maxlength = 15;
char password[maxlength];
int index = 0;
int x = 0;
int y = 0;
int z = 0;

printf("Enter Password: "); //Mike$4
scanf(" %s", password);

do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked

if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}

if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){

if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
return 0;}


Basically every time a requirement is hit I just noted it by incrementing x, y, or z, and if by the end of the password, they all have at least 1, then it's a good password.



Thanks!



I'm asking if there's a better way to code this, because my next CS course in school will mark based on efficiency as well so I wanna make sure I know what makes a C code efficient or not. And of course, how to deal with the space in the password.







c






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 31 '18 at 21:24









Robert Harvey

148k33274418




148k33274418










asked Dec 31 '18 at 21:04









mingming

1333




1333




closed as too broad by Rob K, Sᴀᴍ Onᴇᴌᴀ, user3386109, usr2564301, Retired Ninja Jan 1 at 0:07


Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.









closed as too broad by Rob K, Sᴀᴍ Onᴇᴌᴀ, user3386109, usr2564301, Retired Ninja Jan 1 at 0:07


Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.















  • For what it's worth, you might want to check out the latest NIST guidance about password policies.

    – Daniel Pryden
    Dec 31 '18 at 21:12






  • 2





    It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

    – user3386109
    Dec 31 '18 at 21:15






  • 1





    How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

    – Robert Harvey
    Dec 31 '18 at 21:25













  • When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

    – Jonathan Leffler
    Dec 31 '18 at 21:37













  • For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

    – David C. Rankin
    Dec 31 '18 at 21:49





















  • For what it's worth, you might want to check out the latest NIST guidance about password policies.

    – Daniel Pryden
    Dec 31 '18 at 21:12






  • 2





    It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

    – user3386109
    Dec 31 '18 at 21:15






  • 1





    How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

    – Robert Harvey
    Dec 31 '18 at 21:25













  • When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

    – Jonathan Leffler
    Dec 31 '18 at 21:37













  • For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

    – David C. Rankin
    Dec 31 '18 at 21:49



















For what it's worth, you might want to check out the latest NIST guidance about password policies.

– Daniel Pryden
Dec 31 '18 at 21:12





For what it's worth, you might want to check out the latest NIST guidance about password policies.

– Daniel Pryden
Dec 31 '18 at 21:12




2




2





It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

– user3386109
Dec 31 '18 at 21:15





It's tempting to post a more efficient version of the code, but the correct place to ask for such suggestions is the code review site. As for how to deal with the space character: on any disallowed character you can immediately print the "BAD" message, and break the loop.

– user3386109
Dec 31 '18 at 21:15




1




1





How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

– Robert Harvey
Dec 31 '18 at 21:25







How does your school define "efficiency?" Optimum performance is hardly a useful criteria if all you're doing is checking a single password.

– Robert Harvey
Dec 31 '18 at 21:25















When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

– Jonathan Leffler
Dec 31 '18 at 21:37







When you read the password with scanf("%s", password), you are guaranteed that the reading skip any leading white space (including newlines), and will then stop at the first white space character — a blank, tab, or newline (or one of a few others) — after that. If you want to read a line, use fgets(), but remember that the string returned by fgets() will include the newline (in general, unless there isn't enough space for the whole line).

– Jonathan Leffler
Dec 31 '18 at 21:37















For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

– David C. Rankin
Dec 31 '18 at 21:49







For effective password entry checking, you may want to put the keyboard in non-canonical mode and respond to each keypress. That is the only way you can flag any unwanted character at the time it is entered and before the next key is pressed. See Hide password input on terminal

– David C. Rankin
Dec 31 '18 at 21:49














1 Answer
1






active

oldest

votes


















1















How efficient is my code ....




A common pitfall of coding is focusing on performance, yet the C code has undefined behavior (UB) in it. Fix UB first, then address efficiency.



Buffer overrun



scanf(" %s", password); provided no width limit. A 15-character, or more, password will invoke UB by attempting to write outside password.



Negative char



Early in coding, one is not likely to encounter char with negative values, yet when they happen is...(int ch) functions are a problem. Here, ch must have a value in the unsigned char range or EOF, else UB strikes again.



// isupper(password[index])
isupper((unsigned char) password[index])




With UB out of the way, consider that scanf(" %s", password); can easily takes 100x the time of your while loop. So optimizing your code borders on micro-optimization.



Avoid O(n*n) code



Assume the password is length n and then to find the length of a strings obliges a walk through all n characters via strlen(). Also code is doing n loops calling strlen() each iteration. That is n*n time.



Many compilers today will see that password does not change in the loop and so the result of strlen(password) will be remembered, preventing n*n iterations.



do{
if(index == strlen(password) && x>0 && y>0 && z>0){
...
} while(index <= strlen(password));


Still, it is just as simple to substitute non-iterative code or calculate the length, once, outside the loop.



size_t len = strlen(password);

do {
// if(index == strlen(password) ...
if(password[index] != '' ...
// or
if(index == len ...

// }while(index <= strlen(password));
} while(index <= len);




With such short strings, the length being type int is fine, yet for general array code, including string, size_t is the right-size type for array indexing and lengths.



Using informative names like upper_count rather than x makes for better code.



Sample untested alternative code. Code specifically uses fgetc() versus other input means as a step toward security - there are many more steps.



#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#define PWD_N 6

int main(void) {
size_t maxlength = 15;
char password[maxlength + 1]; // add 1 for
bool upper = false;
bool digit = false;
bool dollar = false;
bool length_ok = true;

printf("Enter Password: "); //Mike$4
fflush(stdout);

size_t i = 0;
for (;;) {
int ch = fgetc(stdin);
if (ch == 'n' || ch == EOF) {
break;
}
if (i < sizeof password - 1) {
password[i++] = ch;
upper |= isupper(ch);
digit |= isdigit(ch);
dollar |= ch == '$';
} else {
length_ok = false; // too long
}
}
password[i] = '';

if (i == PWD_N && length_ok && upper && digit && dollar) {
printf("Good password!n");
} else {
printf("BAD PASSWORDn");
}
return 0;
}





share|improve this answer
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1















    How efficient is my code ....




    A common pitfall of coding is focusing on performance, yet the C code has undefined behavior (UB) in it. Fix UB first, then address efficiency.



    Buffer overrun



    scanf(" %s", password); provided no width limit. A 15-character, or more, password will invoke UB by attempting to write outside password.



    Negative char



    Early in coding, one is not likely to encounter char with negative values, yet when they happen is...(int ch) functions are a problem. Here, ch must have a value in the unsigned char range or EOF, else UB strikes again.



    // isupper(password[index])
    isupper((unsigned char) password[index])




    With UB out of the way, consider that scanf(" %s", password); can easily takes 100x the time of your while loop. So optimizing your code borders on micro-optimization.



    Avoid O(n*n) code



    Assume the password is length n and then to find the length of a strings obliges a walk through all n characters via strlen(). Also code is doing n loops calling strlen() each iteration. That is n*n time.



    Many compilers today will see that password does not change in the loop and so the result of strlen(password) will be remembered, preventing n*n iterations.



    do{
    if(index == strlen(password) && x>0 && y>0 && z>0){
    ...
    } while(index <= strlen(password));


    Still, it is just as simple to substitute non-iterative code or calculate the length, once, outside the loop.



    size_t len = strlen(password);

    do {
    // if(index == strlen(password) ...
    if(password[index] != '' ...
    // or
    if(index == len ...

    // }while(index <= strlen(password));
    } while(index <= len);




    With such short strings, the length being type int is fine, yet for general array code, including string, size_t is the right-size type for array indexing and lengths.



    Using informative names like upper_count rather than x makes for better code.



    Sample untested alternative code. Code specifically uses fgetc() versus other input means as a step toward security - there are many more steps.



    #include <ctype.h>
    #include <stdbool.h>
    #include <stdio.h>
    #define PWD_N 6

    int main(void) {
    size_t maxlength = 15;
    char password[maxlength + 1]; // add 1 for
    bool upper = false;
    bool digit = false;
    bool dollar = false;
    bool length_ok = true;

    printf("Enter Password: "); //Mike$4
    fflush(stdout);

    size_t i = 0;
    for (;;) {
    int ch = fgetc(stdin);
    if (ch == 'n' || ch == EOF) {
    break;
    }
    if (i < sizeof password - 1) {
    password[i++] = ch;
    upper |= isupper(ch);
    digit |= isdigit(ch);
    dollar |= ch == '$';
    } else {
    length_ok = false; // too long
    }
    }
    password[i] = '';

    if (i == PWD_N && length_ok && upper && digit && dollar) {
    printf("Good password!n");
    } else {
    printf("BAD PASSWORDn");
    }
    return 0;
    }





    share|improve this answer






























      1















      How efficient is my code ....




      A common pitfall of coding is focusing on performance, yet the C code has undefined behavior (UB) in it. Fix UB first, then address efficiency.



      Buffer overrun



      scanf(" %s", password); provided no width limit. A 15-character, or more, password will invoke UB by attempting to write outside password.



      Negative char



      Early in coding, one is not likely to encounter char with negative values, yet when they happen is...(int ch) functions are a problem. Here, ch must have a value in the unsigned char range or EOF, else UB strikes again.



      // isupper(password[index])
      isupper((unsigned char) password[index])




      With UB out of the way, consider that scanf(" %s", password); can easily takes 100x the time of your while loop. So optimizing your code borders on micro-optimization.



      Avoid O(n*n) code



      Assume the password is length n and then to find the length of a strings obliges a walk through all n characters via strlen(). Also code is doing n loops calling strlen() each iteration. That is n*n time.



      Many compilers today will see that password does not change in the loop and so the result of strlen(password) will be remembered, preventing n*n iterations.



      do{
      if(index == strlen(password) && x>0 && y>0 && z>0){
      ...
      } while(index <= strlen(password));


      Still, it is just as simple to substitute non-iterative code or calculate the length, once, outside the loop.



      size_t len = strlen(password);

      do {
      // if(index == strlen(password) ...
      if(password[index] != '' ...
      // or
      if(index == len ...

      // }while(index <= strlen(password));
      } while(index <= len);




      With such short strings, the length being type int is fine, yet for general array code, including string, size_t is the right-size type for array indexing and lengths.



      Using informative names like upper_count rather than x makes for better code.



      Sample untested alternative code. Code specifically uses fgetc() versus other input means as a step toward security - there are many more steps.



      #include <ctype.h>
      #include <stdbool.h>
      #include <stdio.h>
      #define PWD_N 6

      int main(void) {
      size_t maxlength = 15;
      char password[maxlength + 1]; // add 1 for
      bool upper = false;
      bool digit = false;
      bool dollar = false;
      bool length_ok = true;

      printf("Enter Password: "); //Mike$4
      fflush(stdout);

      size_t i = 0;
      for (;;) {
      int ch = fgetc(stdin);
      if (ch == 'n' || ch == EOF) {
      break;
      }
      if (i < sizeof password - 1) {
      password[i++] = ch;
      upper |= isupper(ch);
      digit |= isdigit(ch);
      dollar |= ch == '$';
      } else {
      length_ok = false; // too long
      }
      }
      password[i] = '';

      if (i == PWD_N && length_ok && upper && digit && dollar) {
      printf("Good password!n");
      } else {
      printf("BAD PASSWORDn");
      }
      return 0;
      }





      share|improve this answer




























        1












        1








        1








        How efficient is my code ....




        A common pitfall of coding is focusing on performance, yet the C code has undefined behavior (UB) in it. Fix UB first, then address efficiency.



        Buffer overrun



        scanf(" %s", password); provided no width limit. A 15-character, or more, password will invoke UB by attempting to write outside password.



        Negative char



        Early in coding, one is not likely to encounter char with negative values, yet when they happen is...(int ch) functions are a problem. Here, ch must have a value in the unsigned char range or EOF, else UB strikes again.



        // isupper(password[index])
        isupper((unsigned char) password[index])




        With UB out of the way, consider that scanf(" %s", password); can easily takes 100x the time of your while loop. So optimizing your code borders on micro-optimization.



        Avoid O(n*n) code



        Assume the password is length n and then to find the length of a strings obliges a walk through all n characters via strlen(). Also code is doing n loops calling strlen() each iteration. That is n*n time.



        Many compilers today will see that password does not change in the loop and so the result of strlen(password) will be remembered, preventing n*n iterations.



        do{
        if(index == strlen(password) && x>0 && y>0 && z>0){
        ...
        } while(index <= strlen(password));


        Still, it is just as simple to substitute non-iterative code or calculate the length, once, outside the loop.



        size_t len = strlen(password);

        do {
        // if(index == strlen(password) ...
        if(password[index] != '' ...
        // or
        if(index == len ...

        // }while(index <= strlen(password));
        } while(index <= len);




        With such short strings, the length being type int is fine, yet for general array code, including string, size_t is the right-size type for array indexing and lengths.



        Using informative names like upper_count rather than x makes for better code.



        Sample untested alternative code. Code specifically uses fgetc() versus other input means as a step toward security - there are many more steps.



        #include <ctype.h>
        #include <stdbool.h>
        #include <stdio.h>
        #define PWD_N 6

        int main(void) {
        size_t maxlength = 15;
        char password[maxlength + 1]; // add 1 for
        bool upper = false;
        bool digit = false;
        bool dollar = false;
        bool length_ok = true;

        printf("Enter Password: "); //Mike$4
        fflush(stdout);

        size_t i = 0;
        for (;;) {
        int ch = fgetc(stdin);
        if (ch == 'n' || ch == EOF) {
        break;
        }
        if (i < sizeof password - 1) {
        password[i++] = ch;
        upper |= isupper(ch);
        digit |= isdigit(ch);
        dollar |= ch == '$';
        } else {
        length_ok = false; // too long
        }
        }
        password[i] = '';

        if (i == PWD_N && length_ok && upper && digit && dollar) {
        printf("Good password!n");
        } else {
        printf("BAD PASSWORDn");
        }
        return 0;
        }





        share|improve this answer
















        How efficient is my code ....




        A common pitfall of coding is focusing on performance, yet the C code has undefined behavior (UB) in it. Fix UB first, then address efficiency.



        Buffer overrun



        scanf(" %s", password); provided no width limit. A 15-character, or more, password will invoke UB by attempting to write outside password.



        Negative char



        Early in coding, one is not likely to encounter char with negative values, yet when they happen is...(int ch) functions are a problem. Here, ch must have a value in the unsigned char range or EOF, else UB strikes again.



        // isupper(password[index])
        isupper((unsigned char) password[index])




        With UB out of the way, consider that scanf(" %s", password); can easily takes 100x the time of your while loop. So optimizing your code borders on micro-optimization.



        Avoid O(n*n) code



        Assume the password is length n and then to find the length of a strings obliges a walk through all n characters via strlen(). Also code is doing n loops calling strlen() each iteration. That is n*n time.



        Many compilers today will see that password does not change in the loop and so the result of strlen(password) will be remembered, preventing n*n iterations.



        do{
        if(index == strlen(password) && x>0 && y>0 && z>0){
        ...
        } while(index <= strlen(password));


        Still, it is just as simple to substitute non-iterative code or calculate the length, once, outside the loop.



        size_t len = strlen(password);

        do {
        // if(index == strlen(password) ...
        if(password[index] != '' ...
        // or
        if(index == len ...

        // }while(index <= strlen(password));
        } while(index <= len);




        With such short strings, the length being type int is fine, yet for general array code, including string, size_t is the right-size type for array indexing and lengths.



        Using informative names like upper_count rather than x makes for better code.



        Sample untested alternative code. Code specifically uses fgetc() versus other input means as a step toward security - there are many more steps.



        #include <ctype.h>
        #include <stdbool.h>
        #include <stdio.h>
        #define PWD_N 6

        int main(void) {
        size_t maxlength = 15;
        char password[maxlength + 1]; // add 1 for
        bool upper = false;
        bool digit = false;
        bool dollar = false;
        bool length_ok = true;

        printf("Enter Password: "); //Mike$4
        fflush(stdout);

        size_t i = 0;
        for (;;) {
        int ch = fgetc(stdin);
        if (ch == 'n' || ch == EOF) {
        break;
        }
        if (i < sizeof password - 1) {
        password[i++] = ch;
        upper |= isupper(ch);
        digit |= isdigit(ch);
        dollar |= ch == '$';
        } else {
        length_ok = false; // too long
        }
        }
        password[i] = '';

        if (i == PWD_N && length_ok && upper && digit && dollar) {
        printf("Good password!n");
        } else {
        printf("BAD PASSWORDn");
        }
        return 0;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 1 at 0:32

























        answered Dec 31 '18 at 23:43









        chuxchux

        83k872150




        83k872150

















            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas