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

#define DEFAULT_PASS_LENGTH 10
#define PERC_SPECIAL_CHARS 20
#define PERC_NUMBERS_CHARS 40
#define MIX_TIMES 20

char getNumber ();
char getSpec ();
char getAlph ();
void mixString(char*, int);

int main (int argc, char **argv) 
{
	char *pass;	
	int j, i=33, randNo, passLength = DEFAULT_PASS_LENGTH, specChars=0, percSpecChars = PERC_SPECIAL_CHARS;
	int numChars = 0, percNumChars = PERC_NUMBERS_CHARS;

	srand(time(NULL));
	
	if (argc >= 2)
		passLength = atoi(argv[1]);

	pass = malloc(passLength + 1);
	specChars = ((float) passLength / 100) * percSpecChars;
	numChars = ((float) (passLength - specChars) / 100) * percNumChars;

	printf ("Generating %d chars random password ( %d alpha %d numeric %d special ) ...\n", passLength, passLength-specChars-numChars, numChars, specChars);
	
	i = 0;
	for (j = 0; j < numChars; j++) {
		pass[i] = getNumber();
		i++;
	}
	for (j = 0; j < specChars; j++) {
		pass[i] = getSpec();
		i++;
	}
	for (j = 0; j < (passLength - specChars - numChars); j++) {
		pass[i] = getAlph();
		i++;
	}
	pass[i] = '\0';

	mixString(pass, passLength);
	
	printf("%s\n", pass);
}

void mixString(char* string, int length) {
	int i,n; 	char c;
	for (i=0;i<MIX_TIMES;i++){
		
		n = rand() % length;
		c = string[0];
		
		string[0] = string[n];
		string[n] = c;

	}
}

char getNumber () {
	int randNo = 48 + (rand() % 10);
	return (char) randNo;
}

char getSpec () {
	int randNo = 33 + rand() % 32;
	if (randNo > 47)
		randNo += 10;
	if (randNo > 64)
		randNo += 26;
	if (randNo > 96)
		randNo += 26;
	return (char) randNo;
}

char getAlph () {
	int randNo = 65 + rand() % 52;
	if (randNo > 90)
		randNo += 6;
	return (char) randNo;
}
