rpass

Strong password generator for humans
git clone git://git.sgregoratto.me/rpass
Log | Files | Refs | README

rpass.c (2331B)


      1 /*
      2  * Copyright (c) 2017, Tim Kuijsten <info@netsend.nl>
      3  * Copyright (c) 2020, Stephen Gregoratto <dev@sgregoratto.me>
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any
      6  * purpose with or without fee is hereby granted, provided that the above
      7  * copyright notice and this permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  */
     17 
     18 #include "config.h"
     19 #if HAVE_ERR
     20 #include <err.h>
     21 #endif
     22 #include <math.h>
     23 #include <stdint.h>
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <unistd.h>
     27 
     28 #include "rng.h"
     29 
     30 /*
     31  * Dutch three letter "words" that are both visually and phonetically
     32  * unambiguous.
     33  */
     34 /* drop c, g, q, y = 4 bpc */
     35 static const char first[] = "bdfhjklmnprstvwxz";
     36 /* vowels, 2.3 bpc */
     37 static const char secon[] = "aeiou";
     38 /* drop b, c, d, g, q, v, w, y = 3.7 bpc */
     39 static const char third[] = "fhjklmnprstxz";
     40 
     41 int
     42 main(int argc, char **argv)
     43 {
     44 	const double fbpc = log2(sizeof(first) - 1);
     45 	const double sbpc = log2(sizeof(secon) - 1);
     46 	const double tbpc = log2(sizeof(third) - 1);
     47 	double bits = 40.0;
     48 	const char *errstr;
     49 	uint32_t c = 0;
     50 
     51 #if HAVE_PLEDGE
     52 	if (pledge("stdio", NULL) == -1)
     53 		err(1, "pledge");
     54 #endif
     55 
     56 	if (argc > 2) {
     57 		warnx("too many arguments: %s", argv[2]);
     58 		goto usage;
     59 	} else if (argc == 2) {
     60 		if (argv[1][0] == '-' && argv[1][1] == 'h')
     61 			goto usage;
     62 		bits = strtonum(argv[1], 1, 1000, &errstr);
     63 		if (errstr != NULL)
     64 			errx(1, "number of bits is %s: %s", errstr, argv[1]);
     65 	}
     66 
     67 	/* make three letter words */
     68 	do {
     69 		putchar(first[rng_uniform(sizeof(first) - 1)]);
     70 		putchar(secon[rng_uniform(sizeof(secon) - 1)]);
     71 		putchar(third[rng_uniform(sizeof(third) - 1)]);
     72 		bits -= (fbpc + sbpc + tbpc);
     73 
     74 		if (c++ % 2)
     75 			putchar(' ');
     76 	} while (bits > 0);
     77 
     78 	putchar('\n');
     79 
     80 	return 0;
     81 usage:
     82 	fprintf(stderr, "usage: %s [bitlen]\n", getprogname());
     83 
     84 	return 1;
     85 }