Random password generator in C This is a simple password generator. What do you think about it? I am learning C for a while at school and at home. This just has a mix of symbols, lowercase, uppercase and numbers, with a configurable length.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

int main()
{
    int i = 0;
    int n = 0;
    int randomizer = 0;
    srand((unsigned int)(time(NULL)));
    char numbers [] = "1234567890";
    char letter [] = "abcdefghijklmnoqprstuvwyzx";
    char letterr [] = "ABCDEFGHIJKLMNOQPRSTUYWVZX";
    char symbols [] = "!@#$%^&amp;*(){}[]:&lt;&gt;?,./";
    printf("\nHow long password:");
    scanf("%d", &amp;n);
    char password[n];
    randomizer = rand() % 4;
    for (i=0;i&lt;n;i++)
    {
        if(randomizer == 1)
        {
            password[i] = numbers[rand() % 10];
            randomizer = rand() % 4;
            printf("%c", password[i]);
        }
        else if (randomizer == 2)
        {
            password[i] = symbols[rand() % 26];
            randomizer = rand() % 4;
            printf("%c", password[i]);
        }
        else if (randomizer == 3)
        {
            password[i] = letterr[rand() % 26];
            randomizer = rand() % 4;
            printf("%c", password[i]);
        }
        else
        {
            password[i] = letter[rand() % 21];
            randomizer = rand() % 4;
            printf("%c", password[i]);
        }
    }
    return main();
}
I see some things that I think could help you improve your code.

Decompose your program into functions

All of the logic here is in main in one rather long and dense chunk of code.  It would be better to decompose this into separate functions.

Check return values for errors

The call to scanf can fail.  You must check the return values to make sure they haven't or your program may crash (or worse) when given malformed input or due to low system resources.  Rigorous error handling is the difference between mostly working versus bug-free software.  You should strive for the latter.

Use more whitespace to enhance readability of the code

Instead of crowding things together like this:

for (i=0;i&lt;n;i++)


most people find it more easily readable if you use more space:

for (i=0; i &lt; n; i++)


Eliminate "magic numbers"

Instead of hard-coding the constants 26 and 4 in the code, it would be better to use a #define or const and name them.

Avoid scanf if you can

There are so many well known problems with scanf that you're usually better off avoiding it. 

Don't recursively call main

The main() function can be called recursively in C, but it's a bad idea.  You could blow up your stack and there's really no good reason to do that here.  Just use a loop. See https://stackoverflow.com/questions/4238179/calling-main-in-main-in-c for details.

Use a better random number generator

You are currently using 

password[i] = numbers[rand() % 10];


There are a number of problems with this approach. This will generate lower numbers more often than higher ones -- it's not a uniform distribution.  Another problem is that the low order bits of the random number generator are not particularly random, so neither is the result.  On my machine, there's a slight but measurable bias toward 0 with that.  See this answer for details, but I'd recommend changing that to the rand_lim in that link and also duplicated below.

Results

Here's an alternative that uses all of these ideas.  It also gets a length from the command line so there's no need for a prompt or scanf.  It eliminates the need for counting characters and uses the better random number generator mentioned above:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
#include &lt;string.h&gt;

int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
 */

    int divisor = RAND_MAX/(limit+1);
    int retval;

    do { 
        retval = rand() / divisor;
    } while (retval &gt; limit);

    return retval;
}

char picker(const char *charset) {
    return charset[rand_lim(strlen(charset)-1)];
}

int main(int argc, char *argv[])
{
    if (argc != 2) {
        puts("Usage: pwgen len");
        return 1;
    }
    int len = atoi(argv[1]);
    if (len &lt;= 0) {
       puts("Length must be a positive non-zero integer"); 
       return 2;
    }
    const char* groups[] = {
        "1234567890",  // numbers
        "abcdefghijklmnoqprstuvwyzx",  // lowercase
        "ABCDEFGHIJKLMNOQPRSTUYWVZX",  // uppercase
        "!@#$%^&amp;*(){}[]:&lt;&gt;?,./",    // symbols
    };
    const size_t numGroups = sizeof(groups)/sizeof(groups[0]);
    srand((unsigned int)(time(NULL)));

    // only proceed if we got a number
    for ( ; len; --len) {
        unsigned group = rand_lim(numGroups-1);
        putchar(picker(groups[group]));
    }
    putchar('\n');
}