/* program to generate a set of 8 char passwords capable
 * of being printed and read and input from a keyboard using
 * a restricted character set */


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

#define RFILE "random.bin" /* binary file containing random data */

unsigned int getrand(FILE*); /* reads next random 32 bit int from random file */

void mkpasswd(char *pw,FILE *rfh); 
 /* inserts next 8 char password into pw string */

/* set of 54 (23+23+8) easily typed and distinguished characters
 * from which an 8 character password is made up. Easily confused characters
 * when printed i.e. letters ILO and numbers 01 are not in this set */
char charset[]="ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";


int main(void){
	char password[9];
	int npw, i;
	FILE *rfh;
	if((rfh=fopen(RFILE,"r"))==NULL){
	 	printf("error opening random data file\n");
		return 1;
	}
	printf("How many passwords ?\n");
	scanf("%d",&npw);
	for(i=0;i<npw;i++){
		mkpasswd(password,rfh);
		printf("%s\n",password);
	}
	return 0;
}


unsigned int getrand(FILE *rfh){ 
	/* reads next random 32 bit int from random file */
	unsigned int r;
	if(feof(rfh)){
		printf("not enough data in file\n");
		exit(1);
	}
        fread(&r,sizeof(unsigned int),(size_t)1,rfh);
	return r;	
}


void mkpasswd(char *pw, FILE *rfh){ 
	/* inserts next 8 char password into pw string */
	int i=0,j=0,k=0,rem,nchars;
	unsigned int rand;
	nchars=strlen(charset);
	for(i=0;i<2;i++){
		rand=getrand(rfh); /* each rand good for >4 chars */
		for(j=0;j<4;j++){
			rem=rand%nchars;
			pw[k++]=charset[rem];
			rand/=nchars;
		}
	}
	pw[k]='\0';	
	return;
}


