LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 02-09-2009, 04:25 PM   #1
darkangel29
Member
 
Registered: Nov 2004
Location: Puerto Rico
Distribution: Ubuntu 10.04
Posts: 121

Rep: Reputation: 15
help with password generator in C


I'm doing a password generator in C. The program is suppose to generate all the possible combinations for a specify length. I'm able to generate up to 3 characters or more if I keep programming. This is the code so far
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
	int pass_digit = 0;
	int pw_length = 3;
	int i;
	int secondary_digit = 0;
	int counter = 0;
	int possibilities = 0;

	char char1, char2, char3;
	char secondary_char = '0';

	printf("\n.......:::Testing Password Possibility Generator:::........\n");
	printf("Specify Password Length (Max. 3):");
	scanf("%d",&pw_length);

	while (pw_length > 3)
	{
		printf("\nInvalid Length.\n");
		printf("Try again:");
		scanf("%d",&pw_length);
	}

	char pw[pw_length];

//	Loop to initialize the password string
//==========================================================================
	for (i = 0; i < pw_length; i++)
	{
		pw[i] = 0;
		
		if (i + 1 == pw_length)
			pw[i + 1] = '\0';
	}
//==========================================================================

	FILE * fstream;
	fstream = fopen("combos.txt", "w+");


	for (char1 = '0'; char1 <= 'z' ; char1++)
	{
		pw[pass_digit] = char1;
		fprintf(fstream,"%s\n", pw);

		if (char1 == '9')
			char1 = char1 + 7;

		if (char1 == 'Z')
			char1 = char1 + 6;

	}

	pass_digit++;

	if(pass_digit < pw_length)
	{

		for (char1 = '0'; char1 <= 'z' ; char1++)
		{
			pw[pass_digit-1] = char1;

			if (char1 == '9')
				char1 = char1 + 7;

			if (char1 == 'Z')
				char1 = char1 + 6;
			
			for (char2 = '0'; char2 <= 'z' ; char2++)
			{
				pw[pass_digit] = char2;
				fprintf(fstream,"%s\n",pw);

				if (char2 == '9')
					char2 = char2 + 7;

				if (char2 == 'Z')
					char2 = char2 + 6;
			}
		}

		pass_digit++;

		if (pass_digit < pw_length)
		{
			for (char1 = '0'; char1 <= 'z' ; char1++)
			{
				pw[pass_digit-2] = char1;

				if (char1 == '9')
					char1 = char1 + 7;

				if (char1 == 'Z')
					char1 = char1 + 6;
			
				for (char2 = '0'; char2 <= 'z' ; char2++)
				{
					pw[pass_digit-1] = char2;
					fprintf(fstream,"%s\n",pw);

					if (char2 == '9')
						char2 = char2 + 7;

					if (char2 == 'Z')
						char2 = char2 + 6;

					for (char3 = '0'; char3 <= 'z' ; char3++)
					{
						pw[pass_digit] = char3;
						fprintf(fstream,"%s\n",pw);

						if (char3 == '9')
							char3 = char3 + 7;

						if (char3 == 'Z')
							char3 = char3 + 6;
					}
				}
			}
		}
	}

	printf("Its done! Check the combos.txt\n\n");

	fclose(fstream);

	return 1;
}
I'm stuck at this point, I need that the user specify the length of the password and the program to generate all possible combinations. Any ideas how could this be done would be appreciate it. Thanks a lot!!!

Last edited by darkangel29; 02-09-2009 at 04:32 PM.
 
Old 02-09-2009, 04:33 PM   #2
jailbait
Guru
 
Registered: Feb 2003
Location: Blue Ridge Mountain
Distribution: Debian Wheezy, Debian Jessie
Posts: 7,549

Rep: Reputation: 180Reputation: 180
Sorry, I read the question incorrectly.
-------------------
Steve Stites

Last edited by jailbait; 02-09-2009 at 04:34 PM.
 
Old 02-09-2009, 05:20 PM   #3
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by darkangel29 View Post
I'm stuck at this point, I need that the user specify the length of the password and the program to generate all possible combinations. Any ideas how could this be done would be appreciate it. Thanks a lot!!!
This will print all possible passwords for given length and characters that can be included into password:
Code:
#include <stdio.h>
#include <stdlib.h>

void printAllPossiblePasswords(int length, const char* charset){
    char* str;
    const char** counters;
    int i;
    str = malloc(length+1);
    counters = malloc(sizeof(char*)*(length + 1));
    counters[length] = 0;
    str[length] = 0;
    for (i = 0; i < length; i++)
	counters[i] = charset;
    
    while(1){
	for (i = 0; i < length; i++)
	    str[i] = *(counters[i]);
	
	printf("%s\n", str);
	
	counters[0]++;
	for (i = 0; (i < length) && (*(counters[i]) == 0); i++){
	    counters[i] = charset;
	    counters[i+1]++;
	}
	
	if (i == length)
	    break;
    }
    
    free(str);
    free(counters);
}

int main(int argc, char** argv){
    /*printAllPossiblePasswords(8, "1234567890-=qwertyuiop[]asdfghjkl;'\\zxcvbnm,./!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"|ZXCVBNM<>?~`");*/
    printAllPossiblePasswords(6, "1234567890qwertyuiopasdfghjklzxcvbnm");

    return 0;
}
in "genAllPossiblePasswords" charset is a string of characters that can be included into password. Any character can be included several times.
"length" is the length of password you want.
Notice that list will be huge even for small password length (number of possible passwords will be length^strlen(charset) times. This means that for 10 characters with length 3 there will be 1000 possible combinations).
Just compile and run program to understand how it works.

Last edited by ErV; 02-10-2009 at 02:42 AM.
 
Old 02-09-2009, 05:59 PM   #4
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,107

Rep: Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114
Quote:
Originally Posted by ErV View Post
counters = malloc(sizeof(char*)*length + 1);
I expect you meant
counters = malloc(sizeof(char*)*(length + 1));

In case this was homework, I don't think it was appropriate to provide a nearly complete solution.

I assume the thing that was confusing the OP is how to nest a variable number of loops.

You have demonstrated the professional answer: use an array of loop control variables (your "counters").

But I think it would have been better in this case to suggest the easier method, which is a recursive function. That isn't a better method (I think your method is better) but it is easier to understand how it works and easier for a beginner to apply to a wider range of variable nested loops.

Also, the problem statement doesn't say which sequence the strings should come out in, but maybe lexical sequence is assumed.

You varied the leftmost position fastest and rightmost slowest, which makes things a little easier in either your structure or a recursive function, but maybe the extra effort for the more expected sequence would be worth it.

I'm happy to answer questions about the concepts for making this a recursive function if the OP requests, but I don't think doing it is appropriate. (Very likely easier to do than explain, just not as helpful).

Edit: After a look at darkangel29's other posts, this looks less like homework and more like a real attempt to learn, so I'll say more right away regarding the recursive approach, using the simpler version with leftmost char varying fastest.

1) The top level caller allocates a big enough destination buffer and stores the terminating null at the end of it and

2) calls the recursive routine passing a pointer to one character before that terminating null and a count of characters per password, and if you like ErV's idea of a char array to control the character set, pass that as well (otherwise the character set is determined in the code of recursive function).

3) The recursive function loops through each possible char value storing it where the pointer tells it to.

4) In each loop step, after storing the character, if the length it was passed was 1, it prints the string. If the length it was passed is not 1, it calls itself recursively, passing each of pointer and length as one less than the value it received.

Last edited by johnsfine; 02-09-2009 at 06:32 PM.
 
Old 02-10-2009, 02:52 AM   #5
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by johnsfine View Post
I expect you meant
counters = malloc(sizeof(char*)*(length + 1));
Yeah. List of passwords was a bit too long, so I didn't notice possibility of "final crash". Fixed.

Quote:
Originally Posted by johnsfine View Post
In case this was homework, I don't think it was appropriate to provide a nearly complete solution.
Well, problem looked like interesting exercise, so that's why nearly complete solution. On other hand, code isn't basic, so tearing it apart will take some time and will give few ideas/insights, some experience, etc.

Quote:
Originally Posted by johnsfine View Post
You varied the leftmost position fastest and rightmost slowest, which makes things a little easier in either your structure or a recursive function, but maybe the extra effort for the more expected sequence would be worth it.
I thought about changing "rightmost" parameter first (last byte), but I decided that this approach will be a bit clumsy to handle within one loop. Also, it is quite easy to reverse string before printing it. Just change this
Code:
	for (i = 0; i < length; i++)
	    str[i] = *(counters[i]);
or
Code:
	for (i = 0; i < length; i++)
	    str[i] = *(counters[length - i - 1]);
 
Old 02-10-2009, 08:09 AM   #6
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,107

Rep: Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114Reputation: 1114
Quote:
Originally Posted by ErV View Post
Yeah. List of passwords was a bit too long, so I didn't notice possibility of "final crash". Fixed.
I'm sure you were using a version of malloc that rounds request sizes up to multiples of 8 on a system where pointers are 4 or 8 bytes. So I don't think there was any possibility of a crash there.

I commented because I was confident you meant that +1 to be inside () and because the way you had it would be confusing to a beginner, and maybe someone might want to run it under some tool that tests for allocation violations, which would report a violation even if no crash were possible.
 
Old 02-10-2009, 12:08 PM   #7
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by johnsfine View Post
I'm sure you were using a version of malloc that rounds request sizes up to multiples of 8 on a system where pointers are 4 or 8 bytes. So I don't think there was any possibility of a crash there.
I know about that, but it still wouldn't be "right".

Last edited by ErV; 02-10-2009 at 12:10 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Want an easy password generator? Try this :) taskara Linux - General 4 07-24-2005 11:02 PM
written command line password generator lepricaun Programming 6 08-11-2004 12:36 AM
written a password generator in C, get it here lepricaun General 1 08-09-2004 07:12 AM
Help: Need random password generator linuxgamer Linux - Software 5 12-02-2003 01:01 PM
Webmin automatic password generator ToBe Linux - General 2 08-26-2003 09:42 AM


All times are GMT -5. The time now is 09:20 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration