random password generator

Discussion in 'C Programming' started by Army1987, Apr 28, 2007.

  1. Army1987

    Army1987 Guest

    Is there anything wrong with this program? It seems to behave
    strangely if I give stdin EOF when asked for the character set...

    /* BEGIN pwdgen.c */
    #include <stdio.h>
    #include "random.h"
    #include <stdlib.h>
    #include <string.h>

    #define MAX_PWD_LEN 128
    #define MAX_CHARSET 128

    char *pwdgen(size_t length, const char *charset, char *dest);
    char *ord(unsigned n);
    long input(const char *prompt);

    int main(void)
    {
    char charset[MAX_CHARSET] = "";
    char password[MAX_PWD_LEN];
    char *charset_end;
    char prompt[56];
    unsigned long pwd_len;
    printf("Insert characters from which to make passwords "
    "(at most %d characters):\n", MAX_CHARSET - 1);
    fgets(charset, MAX_CHARSET, stdin);
    charset_end = strchr(charset, '\n');
    if (charset_end != NULL)
    *charset_end = '\0';
    else if (getchar() != '\n') {
    fprintf(stderr, "Characters after the %d%s will be discarded\n",
    MAX_CHARSET - 1, ord(MAX_CHARSET - 1));
    scanf("%*[^\n]%*c");
    }
    sprintf(prompt, "Insert password length (at most %d): ",
    MAX_PWD_LEN - 1);
    pwd_len = (unsigned long)input(prompt);
    if (pwd_len > MAX_PWD_LEN - 1) {
    printf("Maximum password length is %d.\n", MAX_PWD_LEN - 1);
    pwd_len = MAX_PWD_LEN - 1;
    }
    fputs("Please wait...", stdout);
    fflush(stdout);
    pwdgen(pwd_len, charset, password);
    puts("\rGenerated password is:");
    puts(password);
    return 0;
    }

    char *pwdgen(size_t length, const char *charset, char *dest)
    /* Fills dest with length random characters from charset */
    {
    if (dest == NULL && (dest = malloc(length+1)) == NULL) {
    perror("Unable to allocate memory");
    return(NULL);
    }
    if (charset == NULL || charset[0] == '\0') {
    fputs("Empty or null charset\n", stderr);
    *dest = '\0';
    } else {
    char *cur = dest;
    size_t n_chars = strlen(charset);
    while (length-- > 0)
    *cur++ = charset[randlong(n_chars)];
    *cur = '\0';
    }
    return dest;
    }

    long input(const char *prompt)
    {
    long result;
    int flag;

    fputs(prompt, stdout);
    fflush(stdout);
    do {
    flag = scanf("%ld", &result);
    switch (flag) {
    case EOF:
    fputs("EOF in stdin\n", stderr);
    exit(EXIT_FAILURE);
    case 0:
    scanf("%*[^\n]%*c");
    fputs("Please enter a numeric value: ", stdout);
    fflush(stdout);
    continue;
    default:
    break;
    }
    } while (flag < 1);
    return result;
    }

    char *ord(unsigned n)
    {
    char *result;
    if (n%100 - n%10 == 10) /* 10th, 11th, 12th ... */
    result = "th";
    else switch (n % 10) {
    case 1: /* 1st, 21st, ... */
    result = "st";
    break;
    case 2: /* 2nd, 22nd, ... */
    result = "nd";
    break;
    case 3: /* 3rd, 23rd, ... */
    result = "rd";
    break;
    default: /* all others */
    result = "th";
    break;
    }
    return result;
    }
    /* END pwdgen.c */

    /* BEGIN random.h */
    #ifndef RANDOM_H__
    #define RANDOM_H__
    unsigned long randlong(unsigned long max);
    unsigned long randomize(unsigned long *max);
    #endif
    /* END random.h */

    /* BEGIN random.c */
    #include <stdio.h>
    #include "random.h"

    unsigned long randlong(unsigned long max)
    /* Return a uniformly distributed random integer from 0 to max-1, or from 0
    to
    * ULONG_MAX if max is 0. Print an error message to stderr if the actual
    range
    * is smaller. */
    {
    static unsigned long randcurr = 0;
    static unsigned long maxrcurr = 0;
    unsigned long result;

    if (max == 0) {
    unsigned long max_;

    result = randomize(&max_);
    if (max_ < (unsigned long)(-1))
    fprintf(stderr, "Not enough entropy. Effective maximum value is
    "
    " %lu.\n", max_);
    return result;
    }
    while (maxrcurr - randcurr < (maxrcurr % max + 1) % max) { /* Unbias */
    randcurr = randomize(&maxrcurr);
    if (maxrcurr < max) {
    fprintf(stderr, "Not enough entropy. Effective maximum value is
    "
    " %lu.\n", max);
    break;
    }
    }
    result = randcurr % max;
    randcurr /= max;
    maxrcurr /= max;
    return result;
    }
    /* END random.c */

    /* BEGIN randomize.c (Linux version -- YMMV) */
    #include <stdio.h>
    #include <stdlib.h>
    unsigned long randomize(unsigned long *max)
    /* Set *max to a large value, and return a uniformly distributed random
    * integer from 0 to *max */
    {
    FILE *random = fopen("/dev/random", "rb");
    unsigned long result;
    unsigned long max_;

    if (random != NULL && fread(&result, sizeof result, 1, random) == 1)
    max_ = (unsigned long)(-1);
    else {
    result = rand();
    max_ = RAND_MAX;
    }
    if (max != NULL)
    *max = max_;
    if (random != NULL)
    fclose(random);
    return result;
    }
    /* END randomize.c */

    --
    char s[]="\16Jsa ukenethr ,cto haCr\n";int main(void){*s*=5;*
    s%=23;putchar(s[0]);return*s-14?main():!putchar(9[s+*s]);}
    Army1987, Apr 28, 2007
    #1
    1. Advertising

  2. Army1987 said:

    > Is there anything wrong with this program? It seems to behave
    > strangely if I give stdin EOF when asked for the character set...


    Don't you think it would be a good idea to test for this condition and
    take appropriate action if it is encountered?

    > printf("Insert characters from which to make passwords "
    > "(at most %d characters):\n", MAX_CHARSET - 1);
    > fgets(charset, MAX_CHARSET, stdin);


    You need to check whether fgets succeeded, and take appropriate action
    if it did not.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Apr 28, 2007
    #2
    1. Advertising

  3. On Sat, 28 Apr 2007 14:44:05 +0200, "Army1987" <>
    wrote:

    >Is there anything wrong with this program? It seems to behave
    >strangely if I give stdin EOF when asked for the character set...


    Define strangely. How do you give stdin EOF? If you give stdin EOF,
    will there ever be a '\n'?

    snip

    > fgets(charset, MAX_CHARSET, stdin);
    > charset_end = strchr(charset, '\n');
    > if (charset_end != NULL)
    > *charset_end = '\0';
    > else if (getchar() != '\n') {
    > fprintf(stderr, "Characters after the %d%s will be discarded\n",
    > MAX_CHARSET - 1, ord(MAX_CHARSET - 1));
    > scanf("%*[^\n]%*c");


    snip


    Remove del for email
    Barry Schwarz, Apr 29, 2007
    #3
  4. Army1987

    Army1987 Guest

    "Barry Schwarz" <> ha scritto nel messaggio
    news:p...
    > On Sat, 28 Apr 2007 14:44:05 +0200, "Army1987" <>
    > wrote:
    >
    >>Is there anything wrong with this program? It seems to behave
    >>strangely if I give stdin EOF when asked for the character set...

    >
    > Define strangely. How do you give stdin EOF? If you give stdin EOF,
    > will there ever be a '\n'?


    Yeah... It turns out that the way I used to end stdin <ot>(pressing ctrl-D,
    in Linux)</ot> works only if it is the first thing input on a line...
    Army1987, May 11, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Martin Maurer
    Replies:
    3
    Views:
    4,837
    Peter
    Apr 19, 2006
  2. globalrev
    Replies:
    4
    Views:
    756
    Gabriel Genellina
    Apr 20, 2008
  3. AAaron123
    Replies:
    2
    Views:
    2,151
    AAaron123
    Jan 16, 2009
  4. AAaron123
    Replies:
    1
    Views:
    1,334
    Oriane
    Jan 16, 2009
  5. VK
    Replies:
    15
    Views:
    1,161
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page