Hi all...
I've been asked to write a password generator in C for a project.

the guidelines are very vague and all I've been told is:

Password must be 9-15 characters long
at least 2 numbers
2 upper/2 lower case latters
1 symbol
and I need to write a dictionary file.

I really don't know where to start as I am very new to C.
Does anyone have any tips...or similar codes I can use as a guideline or to get ideas from?

Thank you :)

Recommended Answers

All 35 Replies

First, you need to use rand() (click me) to generate random characters that can be used in passwords. Do this in a loop. Each time rand() is called check it's return value to find out what kind of character it returned (upper case, lower case, digit, or some other symbol)

If you look at any ascii table, such as this one you will see that all printable characters and symbols have decimal values between 33 and 126 (the space (decimal 32) is also considered printable but not useful for your program). So in order to generate a value between 33 and 126 the math is like this:

int ch = 33 + (rand() % 126)

Now, each time a value is generated search the array of password characters already generated to see if the new value is already in the array. If it is not in the array then add it. If the character is already in the array then ignore it and continue the loop to generate another random character. Since we don't know how many times this loop will repeat itself its best to use a while loop then break out only after the required number of characters have been validated.

Don't attempt to write all that code at one time, you will most likely just get confused if you do. Write a few lines, then compile and test that it works correctly. After that repeat until the program is done.

Thanks alot for the tips!
Hopefully I'll get it done fine without too much hastle.

Additional to what Ancient Dragon has mentioned, you can flick through the source code for a pseudo-random password generator that I wrote a while ago. While it doesn't generate passwords with at least 2 numbers, 2 upper/2 lower case latters and 1 symbol, it may be a useful starting point.

I actually wrote this program today just for fun -- as it turned out I wrote a function that generated a random char between two decimal values, then called it twice to generate 2 digits, twice to get two upper case characters, twice to get two lower case characers, and once to get a symbol. Then I called it 3 more times to generate any random printable character. Finally, call std::random_shuffle() to mix them all up.

But, I'm not about to post the code because that wouldn't help the OP at all to learn how to do it himself.

and I need to write a dictionary file.

I have no idea what that means. What is the file supposed to contain?

Finally, call std::random_shuffle() to mix them all up.

Ahh trust you to resort to C++ ;)

Oops!

Getting absolutly nowhere with this >.<

@AncientDragon you wrote it for fun???
haha

Also,

The dictionary file is a .txt file that keeps a record of all the used passwords.

First, write a function that generates a random number between two values. The two values should be parameters to the two function. For example, if you need to generate a random number between 'a' and 'z', then it should generate one of 26 numbers starting with 'a'.

char GenerateNumber(char start, int quantity)
{

}

I already gave you the formula that generates the random number, just replace the hard-coded values in the forumla I posted with the two parameters to this function and you're done.

After than, main() just needs to call that function twice to get two random numbers between 'a' and 'z', twice more to get characters between 'A' and 'Z', and twice again for '0' to '9'.

char a = GenerateNumber('a',26);
char b = GenerateNumber('A',26);
char c = GenerateNumber('0',10);

The dictionary file is a .txt file that keeps a record of all the used passwords.

That's a password file, not a dictionary file. A dictionary file contains a list of words and possibly their definitions.

This is what I have done so far
I'm just muddled up and anything anyone tells me just doesn't make sense

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

int myMenu();
void genPassword();
void verPassword();
void randNum();



void main()
{    
     char upperCase[] = { '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' }; // Upper case letters for the gen
     char lowercase[] = {'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'}; // Lower case letters for the gen
     int num[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; // numbers for the gen,
     char symbol[] = {'!', '£', '$', '€', '%', '^', '&', '*', '(', ')', '@', '#', '<', '>', '?', '+', '=', '-'}; // symbols for the gen
     int passwordLength; // how long the password will be
     int iMenu; // variable for the menu
     int r = 0

     do
     {
        iMenu = myMenu(); // set iMenu to be the method myMenu()
        switch(iMenu) // switch to choose menu
        {
        case 1:
             {
                 genPassword();
                 break;
             }//End case 1
        case 2:
             {
                 verPassword();
                 break;
             }//End case 2
        case 3:
             {
                 printf("\nGoodbye");
                 break;
             }//End case 3
        default:
             {
                 printf("\nPlease choose a menu choice");
                 break;
             }// End default
        }//End Switch
     }while(iMenu != 3); // End do while

     printf("\n\n");
     system("pause");

}// End main

int myMenu() //The menu
{
    int myChoice;
    system("cls");
    printf("\n Welcome");
    printf("\n 1. Generate Password");
    printf("\n 2. Verify Password");
    printf("\n 3. Exit");
    printf("\n\n Enter a Choice: ");

    fflush(stdin);
    scanf("%d", &myChoice);

    return(myChoice);

}// End myMenu

void randNum()
{
    srand(time(NULL));
    r = rand();
}


void genPassword()
{
    printf("Password generator");

    printf("\n\n");
    system("pause");
} // End genPassword

void verPassword()
{
    printf("Password verifier");

    printf("\n\n");
    system("pause");
} // End verPAssword

Sometimes it's better to just start all over (I've done that before too). Create a new program and code what I said before. Forget about the menu for now, just get the code working that uses rand() to generate a single character using the forumla I previously posted.

Would u be able to help me out with that please?
Its just not making any sense...and I'm sat here since yesterday morning trying to do

int ch = 33 + (rand() % 126)

I posted this 2 days ago! Look at any ascii table, such as this one. You should know that an unsigned char holds values from 0 to 255, that table shows you each one of them. The decimal value of the letter 'A' is 65, while the decimal value of 'a' is 97. We use that information in the formula. rand() % <some number> produces an integer between 0 and <some number>. All we need from the ascii table are some of the values between 0 and 126, the others we can ignore because they are not needed in your program. Now, we really don't want any of the values between 0 and 32 either because none of them are printable, so all we have to do is add 33 to the value returned by rand() % <some number>

The formula now gives you random numbers for all printable characters. But that isn't exactly what you want either. Your instructions say to generate at least two upper case letters. To do that all we have to do is modify the formula slightly. The English alphabet has 26 upper-case letters (not counting numbers). The ascii chart says the value of the first upper case letter is 65. So we need to modify the formula like this:

int ch = 'A' + (rand() % 26)

The second instruction says you have to generate at least 2 lower-case letters. Now the formula needs to look like this:

int ch = 'a' + (rand() % 26)

For the two numeric digits there are only 10 digits

int ch = '0' + (rand() % 10)

Instead of writing a formula for each of the cases as shown previously, we can simplify by writing a more general formula

int ch = lower_bounds + (rand() % quantity)

where 'lower_bounds" is can be 'A', 'a', or '0' and quantity can be either 26 or 10. Now put that into a function with those parameters

char GenerateNumber(char lower_bounds, int quantity)
{
    return lower_bounds + (rand() % quantity);
}

Finally, re-read the post I made just 3 hours ago (the one before your last post). It shows how to call that function to get the values you need.

Note: using this method your program doesn't need to validate the password because it's already in the required format.

char password[15] = {0};
password[0] = GenerateNumber('a',26);
password[1] = GenerateNumber('a',26);
password[2] = GenerateNumber('A',26);
// etc etc.

One thing this does NOT do is guarentee there will be no duplicate characters. It's possible that GenerateNumber() will return the same value twice, the possibility of the happening is pretty slim. You would probably have a better chance of winning the lottery or getting struck by lightening while standing in your house.

Thanks alot, I appreciate it
I'll try it again from the start.

I thought i'd give an update..
I'm not sure if this is the way you tried to explain it to me(When I say tried, I mean, I'm just not a very good learner) But as of now, this is what I have..

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    int i;
    char c;

    srand(time(NULL));
    printf("Your Random Password is: ");
    for (i = 0; i < 5; ++i) {
        c = 'a' + rand() % ('z' - 'a' + 1);
        printf("%c", c);
    }
    for (i = 0; i < 5; ++i) {
        c = 'A' + rand() % ('Z' - 'A' + 1);
        printf("%c", c);
    }
    for (i = 0; i < 5; ++i) {
        c = '1' + rand() % ('1' - '9' + 1);
        printf("%c", c);
    }

    printf("\n\n");
    system("pause");
}

'1' - '9' + 1)

Wrong -- that will produce a negative number

c = '0' + rand() % ('9' - '0' + 1);

You're missing requirement to generate at least 2 symbols.

I'm trying to do it bit my bit so I can try understand it too..
I started off just generating 15 characters, then expanded it to include UPPERCASE, and then some numbers..
Working slowly...but I hope its an acceptable way of doing it.

I hope its an acceptable way of doing it.

Yes, you have exactly the correct approach.

Great, best news I've heard all day... thanks for helping.
I'm sure i'll be back when I need to save the generated passwords to a text file if you wouldnt mind helping with that?

I need to save the password and keep a log of the generated passwords too. :/

Another update:
The password was appearing in the format of hqurdOTHAD376
and now I have it shuffling.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    char password[6 + 6 + 3 + 1];
    int i, j=0, len=sizeof(password)-1;

    srand(time(NULL));
    printf("Your Random Password is: ");
    for (i = 0; i < 6; ++i)
        password[j++] = 'a' + rand() % ('z' - 'a' + 1);
    for (i = 0; i < 6; ++i)
        password[j++] = 'A' + rand() % ('Z' - 'A' + 1);
    for (i = 0; i < 3; ++i)
        password[j++] = '0' + rand() % ('9' - '0' + 1);
    password[j] = '\0';
    for(i = 0; i < sizeof(password)-1; ++i)
        {
        char c = password[i];
        j = rand() % len;
        password[i] = password[j];
        password[j] = c;
        }
    printf("%s\n\n", password);
    system("pause");
}

you should call srand() at the beginning of main() so that rand() will return a different set of random numbers each time your program runs.

srand( (unsigned) time(0) );

I'll do that, thanks :)

I've got it generating a password with 5 Upper, 5 Lower, and 2 numbers... the characters are jumbled up, and the passwords save to a text file.
All i got to do now is add another character, a Symbol, into the mix.. ie !"£$%^&*()><?@#~

Can I do that the same way as I've done for the numbers and letters?

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

FILE*fp; 

int main(void) {

    srand( (unsigned) time(0) );

    char password[5 + 5 + 2 + 1];
    int i, j=0, len=sizeof(password)-1;


    fp = fopen("passwords.txt", "a+"); //Opens the text file to save the Passwords

    srand(time(NULL));
    printf("  Password Generator\n");
    printf("**********************\n");
    printf("Your Random Password is: ");
    printf("\n\n");

    for (i = 0; i < 5; ++i)
        password[j++] = 'a' + rand() % ('z' - 'a' + 1); //Generates 5 random Lowercase characters 

    for (i = 0; i < 5; ++i)
        password[j++] = 'A' + rand() % ('Z' - 'A' + 1); //Generates 5 random Uppercase characters

    for (i = 0; i < 2; ++i)
        password[j++] = '0' + rand() % ('0' - '9' + 1); //Generates 2 random numbers
    password[j] = '\0';
    for(i = 0; i < sizeof(password)-1; ++i)
        {
        char c = password[i];
        j = rand() % len;
        password[i] = password[j];
        password[j] = c;
        }

    printf("%s\n\n", password);
    fprintf(fp, "\n%s", password); //Outputs the Generated Passoword to the text file
    fclose(fp); //Closes the text file
    system("pause");

}

yes, I already posted an example of it.

Ohh... Sorry, I'll go back and check!

Well, maybe I didn't. In any event, it's identical to the others.

33 + (rand() % 15)

15 because there are 15 different symbols that appear in consecutive sequence in the ascii table. Unfortunately, there are a few others that too which can't be accessed this way. If you want to use them too then it might be better to create an array of symbols an access them using the formula (you did that in your original post).

 char symbol[] = {'!', '£', '$', '€', '%', '^', '&', '*', '(', ')', '@', '#', '<', '>', '?', '+', '=', '-'};

 char c = symbol[sizeof(symbol) + (rand() % sizeof(symbol))];

char symbols = "!$%^&*()+=<>?/@";

...
password[j++] = symbols[rand() % strlen(symbols)];

This is what I added to add the symbol.
I think I'm pretty much done now...exept to be able to check the password against the password.txt file to see if it has been generated before.

Thanks for all the help :) APPRECIATE IT :)

Guess Who's back? :)

when I put in a password above 15 characters I get this error?
Its to do with my password length...but its only an extra. ALl my passwords are length 12...and this extra asks to type in a password, and when its over 15 characters this is the error.

Runtime Failure #2 - Stack around the variable 'passwordCheck' was corrupted.

I've been told to

scanf("%s", passwordCheck); // Reads password
if (strlen(passwordCheck) > 15) // Checks length of Password

use fscanf here....but when I do, I get an unhandled exception error

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


FILE*fp; 

char *symbols = "#~!$%^&*()+=<>?/@"; // Random Symbol is generated form this list

int main(void) {

    char password[4 + 4 + 2 + 2 + 1]; // 4 Upper, 4 Lower, 2 Num, 2 Symbols
    int i, j=0, len=sizeof(password)-1;
    int menuNum = 0;
    char passwordCheck[15+1]; // for checking password length



    fp = fopen("passwords.txt", "a+"); //Opens the text file to save the Passwords

    srand(time(NULL));
    printf("       Main Menu\n");
    printf("********************************\n");
    printf("\nEnter 1 to Generate a New Password: ");
    printf("\n\n");
    printf("Enter 2 to Check Old Passwords: ");
    printf("\n\n");
    printf("Enter 3 to Exit. ");
    printf("\n\n");
    scanf("%d", &menuNum); // Reads number

    if (menuNum == 1) // If 1 is entered on the Menu...
    {
        printf("********************************\n");
        printf("\nYour New Password is: \n\n");

    // Each Password will Have 12 Characters(4 Uppercase letters, 4 Lowercase letters, 2 Numbers & 2 Symbols)

    for (i = 0; i < 4; ++i)
        password[j++] = 'a' + rand() % ('z' - 'a' + 1); // Generates 4 random Lowercase characters 

    for (i = 0; i < 4; ++i)
        password[j++] = 'A' + rand() % ('Z' - 'A' + 1); // Generates 4 random Uppercase characters

    for (i = 0; i < 2; ++i)
        password[j++] = '0' + rand() % ('0' - '9' + 1); // Generates 2 random numbers

    for (i = 0; i < 2; ++i)
        password[j++] = symbols[rand() % strlen(symbols)]; // Generates 2 random symbols

    password[j] = '\0';
    for(i = 0; i < sizeof(password)-1; ++i)
        {
        char c = password[i];
        j = rand() % len;
        password[i] = password[j];
        password[j] = c;
        } // Shuffles passwords Characters

    printf("%s\n\n", password);
    printf("********************************\n");
    fprintf(fp, "\n%s", password); // Outputs the Generated Passoword to the text file
    fclose(fp); // Closes the text file
    system("pause");
    }

    else if (menuNum == 2)// If 2 is entered on the Menu...
    {           
        printf("\nEnter your password for checking: ");
        scanf("%s", passwordCheck);  // Reads password
        if (strlen(passwordCheck) > 15) // Checks length of Password
        {
            printf("'%s' is too long. Needs to be less then 15 Characters\n", passwordCheck);
            system("pause");
        }
        else if (strlen(passwordCheck) < 9) // Checks length of Password
        {
            printf("'%s' is too short. Needs to be more then 9 Characters\n", passwordCheck);
            system("pause");
        }
    }

}

The limitation is on lines 13 and 16 -- only room for 15 number of characters in the password. If you want more then change those two lines.

I changed it to

char password[5 + 5 + 5 + 5 + 1]; // 4 Upper, 4 Lower, 2 Num, 2 Symbols
    int i, j=0, len=sizeof(password)-1;
    int menuNum = 0;
    char passwordCheck[20+1];

Just to see...and the verifying length worked...but now when i generate a password it has weird characters in it

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.