mirror of
https://codeberg.org/scip/diceware.git
synced 2025-12-17 02:40:57 +01:00
re-organized source, added Makefile, better Readme, added manpage
This commit is contained in:
49
Makefile
Normal file
49
Makefile
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# This file is part of dicepwgen
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 T.v.Dein.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
|
||||||
|
CFLAGS = -Wall -Wextra -Werror -O1 -g
|
||||||
|
LDFLAGS=
|
||||||
|
OBJS = dicepwgen.o dictfile.o tossing.o
|
||||||
|
DST = dicepwgen
|
||||||
|
PREFIX = /usr/local
|
||||||
|
UID = root
|
||||||
|
GID = 0
|
||||||
|
MAN = dicepwgen.1
|
||||||
|
POD = dicepwgen.pod
|
||||||
|
|
||||||
|
all: $(DST)
|
||||||
|
|
||||||
|
$(DST): $(OBJS)
|
||||||
|
gcc $(OBJS) -o $(DST)
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
gcc -c $(CFLAGS) $*.c -o $*.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(DST)
|
||||||
|
|
||||||
|
man:
|
||||||
|
pod2man $(POD) > $(MAN)
|
||||||
|
|
||||||
|
install: $(DST)
|
||||||
|
install -d -o $(UID) -g $(GID) $(PREFIX)/sbin
|
||||||
|
install -d -o $(UID) -g $(GID) $(PREFIX)/man/man1
|
||||||
|
install -o $(UID) -g $(GID) -m 555 $(DST) $(PREFIX)/sbin/
|
||||||
|
install -o $(UID) -g $(GID) -m 444 $(MAN) $(PREFIX)/man/man1/
|
||||||
67
README.md
67
README.md
@@ -1,11 +1,46 @@
|
|||||||
# diceware
|
## dicepwgen - A diceware password generator
|
||||||
A diceware password generator
|
|
||||||
|
|
||||||
# build
|
This is the README file for the password generator dicepwgen.
|
||||||
|
|
||||||
gcc dice.c -o dice
|
## Documentation
|
||||||
|
|
||||||
# use
|
You can read the documentation without installing the
|
||||||
|
software:
|
||||||
|
|
||||||
|
perldoc udpxd.pod
|
||||||
|
|
||||||
|
If it is already installed, you can read the manual page:
|
||||||
|
|
||||||
|
man udpxd
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
This software doesn't have eny external dependencies, but
|
||||||
|
you need either BSD make or GNU make installed to build it.
|
||||||
|
|
||||||
|
First you need to check out the source code. Skip this, if
|
||||||
|
you have already done so:
|
||||||
|
|
||||||
|
git clone git@github.com:TLINDEN/diceware.git
|
||||||
|
|
||||||
|
Next, change into the newly created directory 'diceware' and
|
||||||
|
compile the source code:
|
||||||
|
|
||||||
|
cd diceware
|
||||||
|
make
|
||||||
|
|
||||||
|
To install, type this command:
|
||||||
|
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
This will install the binary to `$PREFIX/sbin/dicepwgen` and
|
||||||
|
the manual page to `$PREFIX/man/man1/dicepwgen.1`. You can
|
||||||
|
modify `$PREFIX` during installation time like this:
|
||||||
|
|
||||||
|
make install PREFIX=/opt
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
Usage: dice [-tcfvh]
|
Usage: dice [-tcfvh]
|
||||||
@@ -18,9 +53,23 @@ Options:
|
|||||||
-h Print this help screen
|
-h Print this help screen
|
||||||
```
|
```
|
||||||
|
|
||||||
# license
|
## Getting help
|
||||||
|
|
||||||
GPLv3
|
Although I'm happy to hear from udpxd users in private email,
|
||||||
|
that's the best way for me to forget to do something.
|
||||||
|
|
||||||
# author
|
In order to report a bug, unexpected behavior, feature requests
|
||||||
Thomas von Dein
|
or to submit a patch, please open an issue on github:
|
||||||
|
https://github.com/TLINDEN/diceware/issues.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This software is licensed under the GNU GENERAL PUBLIC LICENSE version 3.
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
T.v.Dein <tom AT vondein DOT org>
|
||||||
|
|
||||||
|
## Project homepage
|
||||||
|
|
||||||
|
https://github.com/TLINDEN/diceware
|
||||||
|
|||||||
352
dice.c
352
dice.c
@@ -1,352 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#define DICTFILE "/usr/share/dict/american-english"
|
|
||||||
#define VERSION "1.0"
|
|
||||||
#define RLEN 1024
|
|
||||||
|
|
||||||
int humantoss = 0;
|
|
||||||
int WMIN = 5;
|
|
||||||
int WMAX = 10;
|
|
||||||
|
|
||||||
int usage() {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Generate a random diceware passphrase\n"
|
|
||||||
"Usage: dice [-cfvh]\n"
|
|
||||||
"Options: \n"
|
|
||||||
"-t --humantoss Asks interactively for tossed dices\n"
|
|
||||||
"-c --wordcount <count> Number of words (default: 4)\n"
|
|
||||||
"-f --dictfile <dictfile> Dictionary file to use (default:\n"
|
|
||||||
" /usr/share/dict/american-english)\n"
|
|
||||||
"-l --minlen <count> Minimum word len (default: 5)\n"
|
|
||||||
"-m --maxlen <count> Maximum word len (default: 10)\n"
|
|
||||||
"-v --version Print program version\n"
|
|
||||||
"-h -? --help Print this help screen\n"
|
|
||||||
);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *toss(int count) {
|
|
||||||
/*
|
|
||||||
toss <count> dices. if the global humandice is enabled (option -t),
|
|
||||||
then ask the human to toss dices and enter the numbers interactively.
|
|
||||||
otherwise generate tosses from /dev/random.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FILE *RAND;
|
|
||||||
int i;
|
|
||||||
int pos = 0;
|
|
||||||
uint8_t onedice;
|
|
||||||
unsigned char *tosses = NULL;
|
|
||||||
unsigned char *rand = NULL;
|
|
||||||
size_t len;
|
|
||||||
ssize_t linelen;
|
|
||||||
|
|
||||||
if(humantoss) {
|
|
||||||
char *line = NULL;
|
|
||||||
char digit[2];
|
|
||||||
digit[1] = '\0';
|
|
||||||
|
|
||||||
RETRY:
|
|
||||||
fprintf(stderr, "enter 5 digits, each between 1-6\n");
|
|
||||||
linelen = getline(&line, &len, stdin);
|
|
||||||
tosses = malloc((size_t)count);
|
|
||||||
|
|
||||||
if(linelen < 6) /* 5 digits max allowed */
|
|
||||||
goto RETRY;
|
|
||||||
|
|
||||||
for(i=0; i<count; i++) { /* only digits allowed */
|
|
||||||
if(isdigit(line[i]) == 0)
|
|
||||||
goto RETRY;
|
|
||||||
|
|
||||||
digit[0] = line[i];
|
|
||||||
onedice = atoi(digit);
|
|
||||||
|
|
||||||
if (onedice < 1 || onedice > 6) /* no dice digit */
|
|
||||||
goto RETRY;
|
|
||||||
|
|
||||||
tosses[i] = onedice;
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rand = malloc(RLEN);
|
|
||||||
|
|
||||||
if((RAND = fopen("/dev/urandom", "rb")) == NULL) {
|
|
||||||
perror("Could not open /dev/urandom");
|
|
||||||
}
|
|
||||||
|
|
||||||
fread(rand, RLEN, 1, RAND);
|
|
||||||
fclose(RAND);
|
|
||||||
|
|
||||||
tosses = malloc((size_t)count);
|
|
||||||
|
|
||||||
for(i=0; i<RLEN; i++) {
|
|
||||||
onedice = rand[i];
|
|
||||||
onedice &= 7; /* only use the last 3 bits, 0-7 */
|
|
||||||
onedice %= 6; /* 6 is the max */
|
|
||||||
if(onedice >= 1 && onedice <= 6) {
|
|
||||||
tosses[pos] = onedice;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
if(pos == count)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(rand);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tosses;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rand_lim(int limit) {
|
|
||||||
/*
|
|
||||||
return a random number in the range [0..limit)
|
|
||||||
*/
|
|
||||||
|
|
||||||
int divisor = RAND_MAX/limit;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
do {
|
|
||||||
retval = rand() / divisor;
|
|
||||||
} while (retval == limit);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *incr_dicedigit(int *digits) {
|
|
||||||
/*
|
|
||||||
increment an array of dice digits, we expect the first to
|
|
||||||
be a multiple of 10000, the 2nd a multiple of 1000 and so on.
|
|
||||||
*/
|
|
||||||
if(digits[4] == 6) {
|
|
||||||
digits[4] = 1;
|
|
||||||
if(digits[3] == 60) {
|
|
||||||
digits[3] = 10;
|
|
||||||
if(digits[2] == 600) {
|
|
||||||
digits[2] = 100;
|
|
||||||
if(digits[1] == 6000) {
|
|
||||||
digits[1] = 1000;
|
|
||||||
digits[0] += 10000; /* may overflow to 71111, must be catched by caller */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
digits[1] += 1000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
digits[2] += 100;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
digits[3] += 10;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
digits[4]++;
|
|
||||||
|
|
||||||
return digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_dicenum(int *digits) {
|
|
||||||
/*
|
|
||||||
get the actual number of an array of dice digits
|
|
||||||
*/
|
|
||||||
int i = 0;
|
|
||||||
int pos = 0;
|
|
||||||
for(i=0; i<5; i++)
|
|
||||||
pos += digits[i];
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char **fetch_dict(char *dictfile) {
|
|
||||||
/*
|
|
||||||
read in the dictionary file. we generate an array of max
|
|
||||||
66666 entries from the dictionary, each entry's index will
|
|
||||||
be a dice number (1 <=> 6). to enhance randomness, we jump
|
|
||||||
over a number of lines (1-32 lines) and start from the beginning
|
|
||||||
of the file if we reach the end before our array is full.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char **words;
|
|
||||||
int pos, i, next, jump;
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
ssize_t linelen;
|
|
||||||
FILE *DICT;
|
|
||||||
int *digits;
|
|
||||||
|
|
||||||
if((DICT = fopen(dictfile, "rb")) == NULL) {
|
|
||||||
perror("Could not open dictfile");
|
|
||||||
}
|
|
||||||
|
|
||||||
words = malloc(66666 * sizeof(char *));
|
|
||||||
digits = malloc(5);
|
|
||||||
jump = rand_lim(32);
|
|
||||||
|
|
||||||
digits[0] = 10000;
|
|
||||||
digits[1] = 1000;
|
|
||||||
digits[2] = 100;
|
|
||||||
digits[3] = 10;
|
|
||||||
digits[4] = 1;
|
|
||||||
|
|
||||||
pos = 11111;
|
|
||||||
next = 0;
|
|
||||||
|
|
||||||
for(i=0; i<6666; i++)
|
|
||||||
words[i] = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
LOOP:
|
|
||||||
while ((linelen = getline(&line, &len, DICT)) != -1) {
|
|
||||||
if(jump > 0) {
|
|
||||||
jump--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jump = rand_lim(32);
|
|
||||||
}
|
|
||||||
if(linelen >= WMIN+1 && linelen <= WMAX+1) {
|
|
||||||
line[linelen-1] = '\0'; /* remove newline */
|
|
||||||
|
|
||||||
for(i=0; i<linelen-1; i++) {
|
|
||||||
if(isalpha((int)line[i]) == 0) {
|
|
||||||
next = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(next) {
|
|
||||||
next = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
words[pos] = malloc(linelen);
|
|
||||||
strncpy( words[pos], line, linelen);
|
|
||||||
//fprintf(stdout, "%d: %s\n", pos, line);
|
|
||||||
|
|
||||||
digits = incr_dicedigit(digits);
|
|
||||||
pos = get_dicenum(digits);
|
|
||||||
|
|
||||||
/* this is what pos gets next after 66666, which is max reachable with 5 dices */
|
|
||||||
if(pos == 71111)
|
|
||||||
break;
|
|
||||||
} /* endif word 4<=>10 */
|
|
||||||
} /* while read */
|
|
||||||
|
|
||||||
if(pos < 66666) {
|
|
||||||
fseek(DICT, 0L, SEEK_SET);
|
|
||||||
goto LOOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(DICT);
|
|
||||||
free(line);
|
|
||||||
free(digits);
|
|
||||||
|
|
||||||
return words;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getwords(char *dictfile, int count) {
|
|
||||||
/*
|
|
||||||
initiate dice tossing, extract matching number of words
|
|
||||||
froom the wordlist and print it.
|
|
||||||
*/
|
|
||||||
char **words;
|
|
||||||
int i, pos, one, two, three, four, five;
|
|
||||||
int *tossed;
|
|
||||||
unsigned char *tosses;
|
|
||||||
|
|
||||||
words = fetch_dict(dictfile);
|
|
||||||
|
|
||||||
tossed = malloc(count * sizeof(int));
|
|
||||||
|
|
||||||
for(i=0; i<count; i++) {
|
|
||||||
tosses = toss(5);
|
|
||||||
|
|
||||||
one = tosses[0] * 10000;
|
|
||||||
two = tosses[1] * 1000;
|
|
||||||
three = tosses[2] * 100;
|
|
||||||
four = tosses[3] * 10;
|
|
||||||
five = tosses[4];
|
|
||||||
|
|
||||||
pos = one + two + three + four + five;
|
|
||||||
|
|
||||||
tossed[i] = pos;
|
|
||||||
|
|
||||||
free(tosses);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<count; i++) {
|
|
||||||
fprintf(stdout, "%s ", words[tossed[i]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stdout, "\n");
|
|
||||||
|
|
||||||
free(tossed);
|
|
||||||
|
|
||||||
for(i=0; i<6666; i++)
|
|
||||||
if(words[i] != NULL)
|
|
||||||
free(words[i]);
|
|
||||||
|
|
||||||
free(words);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv) {
|
|
||||||
int count = 4;
|
|
||||||
char *dictfile = NULL;
|
|
||||||
unsigned char *tosses = NULL;
|
|
||||||
int opt;
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
|
||||||
{ "wordcount", required_argument, NULL, 'c' },
|
|
||||||
{ "minlen", required_argument, NULL, 'l' },
|
|
||||||
{ "maxlen", required_argument, NULL, 'm' },
|
|
||||||
{ "humantoss", required_argument, NULL, 't' },
|
|
||||||
{ "dictfile", required_argument, NULL, 'f' },
|
|
||||||
{ "version", no_argument, NULL, 'v' },
|
|
||||||
{ "help", no_argument, NULL, 'h' },
|
|
||||||
};
|
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "l:m:tf:c:vh?", longopts, NULL)) != -1) {
|
|
||||||
switch (opt) {
|
|
||||||
case 'v':
|
|
||||||
fprintf(stderr, "This is %s version %s\n", argv[0], VERSION);
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
case '?':
|
|
||||||
return usage();
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
count = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
WMIN = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
WMAX = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
humantoss = 1;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
dictfile = malloc(strlen(optarg));
|
|
||||||
strncpy(dictfile, optarg, strlen(optarg));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(dictfile == NULL) {
|
|
||||||
dictfile = DICTFILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
getwords(dictfile, count);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
193
dicepwgen.1
Normal file
193
dicepwgen.1
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||||
|
.\"
|
||||||
|
.\" Standard preamble:
|
||||||
|
.\" ========================================================================
|
||||||
|
.de Sp \" Vertical space (when we can't use .PP)
|
||||||
|
.if t .sp .5v
|
||||||
|
.if n .sp
|
||||||
|
..
|
||||||
|
.de Vb \" Begin verbatim text
|
||||||
|
.ft CW
|
||||||
|
.nf
|
||||||
|
.ne \\$1
|
||||||
|
..
|
||||||
|
.de Ve \" End verbatim text
|
||||||
|
.ft R
|
||||||
|
.fi
|
||||||
|
..
|
||||||
|
.\" Set up some character translations and predefined strings. \*(-- will
|
||||||
|
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||||
|
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||||
|
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||||
|
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||||
|
.\" nothing in troff, for use with C<>.
|
||||||
|
.tr \(*W-
|
||||||
|
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||||
|
.ie n \{\
|
||||||
|
. ds -- \(*W-
|
||||||
|
. ds PI pi
|
||||||
|
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||||
|
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||||
|
. ds L" ""
|
||||||
|
. ds R" ""
|
||||||
|
. ds C` ""
|
||||||
|
. ds C' ""
|
||||||
|
'br\}
|
||||||
|
.el\{\
|
||||||
|
. ds -- \|\(em\|
|
||||||
|
. ds PI \(*p
|
||||||
|
. ds L" ``
|
||||||
|
. ds R" ''
|
||||||
|
. ds C`
|
||||||
|
. ds C'
|
||||||
|
'br\}
|
||||||
|
.\"
|
||||||
|
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||||
|
.ie \n(.g .ds Aq \(aq
|
||||||
|
.el .ds Aq '
|
||||||
|
.\"
|
||||||
|
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||||
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||||
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||||
|
.\" output yourself in some meaningful fashion.
|
||||||
|
.\"
|
||||||
|
.\" Avoid warning from groff about undefined register 'F'.
|
||||||
|
.de IX
|
||||||
|
..
|
||||||
|
.nr rF 0
|
||||||
|
.if \n(.g .if rF .nr rF 1
|
||||||
|
.if (\n(rF:(\n(.g==0)) \{
|
||||||
|
. if \nF \{
|
||||||
|
. de IX
|
||||||
|
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||||
|
..
|
||||||
|
. if !\nF==2 \{
|
||||||
|
. nr % 0
|
||||||
|
. nr F 2
|
||||||
|
. \}
|
||||||
|
. \}
|
||||||
|
.\}
|
||||||
|
.rr rF
|
||||||
|
.\"
|
||||||
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
||||||
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
||||||
|
. \" fudge factors for nroff and troff
|
||||||
|
.if n \{\
|
||||||
|
. ds #H 0
|
||||||
|
. ds #V .8m
|
||||||
|
. ds #F .3m
|
||||||
|
. ds #[ \f1
|
||||||
|
. ds #] \fP
|
||||||
|
.\}
|
||||||
|
.if t \{\
|
||||||
|
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
||||||
|
. ds #V .6m
|
||||||
|
. ds #F 0
|
||||||
|
. ds #[ \&
|
||||||
|
. ds #] \&
|
||||||
|
.\}
|
||||||
|
. \" simple accents for nroff and troff
|
||||||
|
.if n \{\
|
||||||
|
. ds ' \&
|
||||||
|
. ds ` \&
|
||||||
|
. ds ^ \&
|
||||||
|
. ds , \&
|
||||||
|
. ds ~ ~
|
||||||
|
. ds /
|
||||||
|
.\}
|
||||||
|
.if t \{\
|
||||||
|
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
||||||
|
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
||||||
|
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
||||||
|
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
||||||
|
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
||||||
|
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
||||||
|
.\}
|
||||||
|
. \" troff and (daisy-wheel) nroff accents
|
||||||
|
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
||||||
|
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
||||||
|
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
||||||
|
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
||||||
|
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
||||||
|
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
||||||
|
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
||||||
|
.ds ae a\h'-(\w'a'u*4/10)'e
|
||||||
|
.ds Ae A\h'-(\w'A'u*4/10)'E
|
||||||
|
. \" corrections for vroff
|
||||||
|
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
||||||
|
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
||||||
|
. \" for low resolution devices (crt and lpr)
|
||||||
|
.if \n(.H>23 .if \n(.V>19 \
|
||||||
|
\{\
|
||||||
|
. ds : e
|
||||||
|
. ds 8 ss
|
||||||
|
. ds o a
|
||||||
|
. ds d- d\h'-1'\(ga
|
||||||
|
. ds D- D\h'-1'\(hy
|
||||||
|
. ds th \o'bp'
|
||||||
|
. ds Th \o'LP'
|
||||||
|
. ds ae ae
|
||||||
|
. ds Ae AE
|
||||||
|
.\}
|
||||||
|
.rm #[ #] #H #V #F C
|
||||||
|
.\" ========================================================================
|
||||||
|
.\"
|
||||||
|
.IX Title "DICEPWGEN 1"
|
||||||
|
.TH DICEPWGEN 1 "2015-08-01" "perl v5.18.2" "User Contributed Perl Documentation"
|
||||||
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
|
.\" way too many mistakes in technical documents.
|
||||||
|
.if n .ad l
|
||||||
|
.nh
|
||||||
|
.SH "NAME"
|
||||||
|
dicepwgen \- A diceware password generator
|
||||||
|
.SH "SYNOPSIS"
|
||||||
|
.IX Header "SYNOPSIS"
|
||||||
|
.Vb 10
|
||||||
|
\& Usage: dice [\-cfvh]
|
||||||
|
\& Options:
|
||||||
|
\& \-t \-\-humantoss Asks interactively for tossed dices
|
||||||
|
\& \-c \-\-wordcount <count> Number of words (default: 4)
|
||||||
|
\& \-f \-\-dictfile <dictfile> Dictionary file to use (default:
|
||||||
|
\& /usr/share/dict/american\-english)
|
||||||
|
\& \-l \-\-minlen <count> Minimum word len (default: 5)
|
||||||
|
\& \-m \-\-maxlen <count> Maximum word len (default: 10)
|
||||||
|
\& \-v \-\-version Print program version
|
||||||
|
\& \-h \-? \-\-help Print this help screen
|
||||||
|
.Ve
|
||||||
|
.SH "DESCRIPTION"
|
||||||
|
.IX Header "DESCRIPTION"
|
||||||
|
dicepwgen generates a diceware password using a dictionary
|
||||||
|
file. By default it uses pseudo random dice tosses, but
|
||||||
|
it is also possible to use real dices and enter the numbers
|
||||||
|
by using the option \fB\-t\fR.
|
||||||
|
.PP
|
||||||
|
The option \fB\-c\fR can be used to tweak the number of words
|
||||||
|
to output. The options \fB\-l\fR and \fB\-m\fR can be used to tweak
|
||||||
|
minimum and maximum word length.
|
||||||
|
.PP
|
||||||
|
You can tell dicepwgen to use another dictionary file with
|
||||||
|
the option \fB\-f\fR.
|
||||||
|
.PP
|
||||||
|
The program only uses words which contain 7bit \s-1ASCII\s0 letters
|
||||||
|
(a\-zA-Z), which are easier for password usage anyway.
|
||||||
|
.SH "FILES"
|
||||||
|
.IX Header "FILES"
|
||||||
|
\&\fB/usr/share/dict/american\-english\fR: default dictionary file.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IX Header "SEE ALSO"
|
||||||
|
<http://world.std.com/~reinhold/diceware.html>
|
||||||
|
.PP
|
||||||
|
<https://xkcd.com/936/>.
|
||||||
|
.SH "BUGS"
|
||||||
|
.IX Header "BUGS"
|
||||||
|
In order to report a bug, unexpected behavior, feature requests
|
||||||
|
or to submit a patch, please open an issue on github:
|
||||||
|
<https://github.com/TLINDEN/diceware/issues>.
|
||||||
|
.SH "LICENSE"
|
||||||
|
.IX Header "LICENSE"
|
||||||
|
This software is licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3.
|
||||||
|
.PP
|
||||||
|
Copyright (c) 2015 by T. v. Dein.
|
||||||
|
.SH "AUTHORS"
|
||||||
|
.IX Header "AUTHORS"
|
||||||
|
T.v.Dein \fBtom \s-1AT\s0 vondein \s-1DOT\s0 org\fR
|
||||||
146
dicepwgen.c
Normal file
146
dicepwgen.c
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dicepwgen.h"
|
||||||
|
|
||||||
|
int usage() {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Generate a random diceware passphrase\n"
|
||||||
|
"Usage: dice [-tcfvh]\n"
|
||||||
|
"Options: \n"
|
||||||
|
"-t --humantoss Asks interactively for tossed dices\n"
|
||||||
|
"-c --wordcount <count> Number of words (default: 4)\n"
|
||||||
|
"-f --dictfile <dictfile> Dictionary file to use (default:\n"
|
||||||
|
" /usr/share/dict/american-english)\n"
|
||||||
|
"-l --minlen <count> Minimum word len (default: 5)\n"
|
||||||
|
"-m --maxlen <count> Maximum word len (default: 10)\n"
|
||||||
|
"-v --version Print program version\n"
|
||||||
|
"-h -? --help Print this help screen\n"
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
int count = 4;
|
||||||
|
char *dictfile = NULL;
|
||||||
|
unsigned char *tosses = NULL;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
WMIN = 6;
|
||||||
|
WMAX = 10;
|
||||||
|
humantoss = 0;
|
||||||
|
|
||||||
|
static struct option longopts[] = {
|
||||||
|
{ "wordcount", required_argument, NULL, 'c' },
|
||||||
|
{ "minlen", required_argument, NULL, 'l' },
|
||||||
|
{ "maxlen", required_argument, NULL, 'm' },
|
||||||
|
{ "humantoss", required_argument, NULL, 't' },
|
||||||
|
{ "dictfile", required_argument, NULL, 'f' },
|
||||||
|
{ "version", no_argument, NULL, 'v' },
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((opt = getopt_long(argc, argv, "l:m:tf:c:vh?", longopts, NULL)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'v':
|
||||||
|
fprintf(stderr, "This is %s version %s\n", argv[0], VERSION);
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
return usage();
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
count = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
WMIN = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
WMAX = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
humantoss = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
dictfile = malloc(strlen(optarg));
|
||||||
|
strncpy(dictfile, optarg, strlen(optarg));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return usage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(dictfile == NULL) {
|
||||||
|
dictfile = DICTFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
getwords(dictfile, count);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getwords(char *dictfile, int count) {
|
||||||
|
/*
|
||||||
|
initiate dice tossing, extract matching number of words
|
||||||
|
froom the wordlist and print it.
|
||||||
|
*/
|
||||||
|
char **words;
|
||||||
|
int i, pos, one, two, three, four, five;
|
||||||
|
int *tossed;
|
||||||
|
unsigned char *tosses;
|
||||||
|
|
||||||
|
words = fetch_dict(dictfile);
|
||||||
|
|
||||||
|
tossed = malloc(count * sizeof(int));
|
||||||
|
|
||||||
|
for(i=0; i<count; i++) {
|
||||||
|
tosses = toss(5);
|
||||||
|
|
||||||
|
one = tosses[0] * 10000;
|
||||||
|
two = tosses[1] * 1000;
|
||||||
|
three = tosses[2] * 100;
|
||||||
|
four = tosses[3] * 10;
|
||||||
|
five = tosses[4];
|
||||||
|
|
||||||
|
pos = one + two + three + four + five;
|
||||||
|
|
||||||
|
tossed[i] = pos;
|
||||||
|
|
||||||
|
free(tosses);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<count; i++) {
|
||||||
|
fprintf(stdout, "%s ", words[tossed[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
free(tossed);
|
||||||
|
|
||||||
|
for(i=0; i<6666; i++)
|
||||||
|
if(words[i] != NULL)
|
||||||
|
free(words[i]);
|
||||||
|
|
||||||
|
free(words);
|
||||||
|
}
|
||||||
48
dicepwgen.h
Normal file
48
dicepwgen.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_DICE_H
|
||||||
|
#define HAVE_DICE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "dictfile.h"
|
||||||
|
#include "tossing.h"
|
||||||
|
|
||||||
|
#define DICTFILE "/usr/share/dict/american-english"
|
||||||
|
#define VERSION "1.0"
|
||||||
|
#define RLEN 1024
|
||||||
|
|
||||||
|
int humantoss;
|
||||||
|
int WMIN;
|
||||||
|
int WMAX;
|
||||||
|
|
||||||
|
int usage();
|
||||||
|
int main (int argc, char **argv);
|
||||||
|
void getwords(char *dictfile, int count);
|
||||||
|
|
||||||
|
#endif
|
||||||
61
dicepwgen.pod
Normal file
61
dicepwgen.pod
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
dicepwgen - A diceware password generator
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
Usage: dice [-cfvh]
|
||||||
|
Options:
|
||||||
|
-t --humantoss Asks interactively for tossed dices
|
||||||
|
-c --wordcount <count> Number of words (default: 4)
|
||||||
|
-f --dictfile <dictfile> Dictionary file to use (default:
|
||||||
|
/usr/share/dict/american-english)
|
||||||
|
-l --minlen <count> Minimum word len (default: 5)
|
||||||
|
-m --maxlen <count> Maximum word len (default: 10)
|
||||||
|
-v --version Print program version
|
||||||
|
-h -? --help Print this help screen
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
dicepwgen generates a diceware password using a dictionary
|
||||||
|
file. By default it uses pseudo random dice tosses, but
|
||||||
|
it is also possible to use real dices and enter the numbers
|
||||||
|
by using the option B<-t>.
|
||||||
|
|
||||||
|
The option B<-c> can be used to tweak the number of words
|
||||||
|
to output. The options B<-l> and B<-m> can be used to tweak
|
||||||
|
minimum and maximum word length.
|
||||||
|
|
||||||
|
You can tell dicepwgen to use another dictionary file with
|
||||||
|
the option B<-f>.
|
||||||
|
|
||||||
|
The program only uses words which contain 7bit ASCII letters
|
||||||
|
(a-zA-Z), which are easier for password usage anyway.
|
||||||
|
|
||||||
|
=head1 FILES
|
||||||
|
|
||||||
|
B</usr/share/dict/american-english>: default dictionary file.
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
L<http://world.std.com/~reinhold/diceware.html>
|
||||||
|
|
||||||
|
L<https://xkcd.com/936/>.
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
In order to report a bug, unexpected behavior, feature requests
|
||||||
|
or to submit a patch, please open an issue on github:
|
||||||
|
L<https://github.com/TLINDEN/diceware/issues>.
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
This software is licensed under the GNU GENERAL PUBLIC LICENSE version 3.
|
||||||
|
|
||||||
|
Copyright (c) 2015 by T. v. Dein.
|
||||||
|
|
||||||
|
=head1 AUTHORS
|
||||||
|
|
||||||
|
T.v.Dein B<tom AT vondein DOT org>
|
||||||
|
|
||||||
|
=cut
|
||||||
139
dictfile.c
Normal file
139
dictfile.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dictfile.h"
|
||||||
|
|
||||||
|
int *incr_dicedigit(int *digits) {
|
||||||
|
/*
|
||||||
|
increment an array of dice digits, we expect the first to
|
||||||
|
be a multiple of 10000, the 2nd a multiple of 1000 and so on.
|
||||||
|
*/
|
||||||
|
if(digits[4] == 6) {
|
||||||
|
digits[4] = 1;
|
||||||
|
if(digits[3] == 60) {
|
||||||
|
digits[3] = 10;
|
||||||
|
if(digits[2] == 600) {
|
||||||
|
digits[2] = 100;
|
||||||
|
if(digits[1] == 6000) {
|
||||||
|
digits[1] = 1000;
|
||||||
|
digits[0] += 10000; /* may overflow to 71111, must be catched by caller */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
digits[1] += 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
digits[2] += 100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
digits[3] += 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
digits[4]++;
|
||||||
|
|
||||||
|
return digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **fetch_dict(char *dictfile) {
|
||||||
|
/*
|
||||||
|
read in the dictionary file. we generate an array of max
|
||||||
|
66666 entries from the dictionary, each entry's index will
|
||||||
|
be a dice number (1 <=> 6). to enhance randomness, we jump
|
||||||
|
over a number of lines (1-32 lines) and start from the beginning
|
||||||
|
of the file if we reach the end before our array is full.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char **words;
|
||||||
|
int pos, i, next, jump;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t linelen;
|
||||||
|
FILE *DICT;
|
||||||
|
int *digits;
|
||||||
|
|
||||||
|
if((DICT = fopen(dictfile, "rb")) == NULL) {
|
||||||
|
perror("Could not open dictfile");
|
||||||
|
}
|
||||||
|
|
||||||
|
words = malloc(66666 * sizeof(char *));
|
||||||
|
digits = malloc(5);
|
||||||
|
jump = rand_lim(32);
|
||||||
|
|
||||||
|
digits[0] = 10000;
|
||||||
|
digits[1] = 1000;
|
||||||
|
digits[2] = 100;
|
||||||
|
digits[3] = 10;
|
||||||
|
digits[4] = 1;
|
||||||
|
|
||||||
|
pos = 11111;
|
||||||
|
next = 0;
|
||||||
|
|
||||||
|
for(i=0; i<6666; i++)
|
||||||
|
words[i] = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
LOOP:
|
||||||
|
while ((linelen = getline(&line, &len, DICT)) != -1) {
|
||||||
|
if(jump > 0) {
|
||||||
|
jump--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jump = rand_lim(32);
|
||||||
|
}
|
||||||
|
if(linelen >= WMIN+1 && linelen <= WMAX+1) {
|
||||||
|
line[linelen-1] = '\0'; /* remove newline */
|
||||||
|
|
||||||
|
for(i=0; i<linelen-1; i++) {
|
||||||
|
if(isalpha((int)line[i]) == 0) {
|
||||||
|
next = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(next) {
|
||||||
|
next = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
words[pos] = malloc(linelen);
|
||||||
|
strncpy( words[pos], line, linelen);
|
||||||
|
//fprintf(stdout, "%d: %s\n", pos, line);
|
||||||
|
|
||||||
|
digits = incr_dicedigit(digits);
|
||||||
|
pos = get_dicenum(digits);
|
||||||
|
|
||||||
|
/* this is what pos gets next after 66666, which is max reachable with 5 dices */
|
||||||
|
if(pos == 71111)
|
||||||
|
break;
|
||||||
|
} /* endif word 4<=>10 */
|
||||||
|
} /* while read */
|
||||||
|
|
||||||
|
if(pos < 66666) {
|
||||||
|
fseek(DICT, 0L, SEEK_SET);
|
||||||
|
goto LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(DICT);
|
||||||
|
free(line);
|
||||||
|
free(digits);
|
||||||
|
|
||||||
|
return words;
|
||||||
|
}
|
||||||
40
dictfile.h
Normal file
40
dictfile.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_DICTFILE_H
|
||||||
|
#define HAVE_DICTFILE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "tossing.h"
|
||||||
|
|
||||||
|
extern int WMIN;
|
||||||
|
extern int WMAX;
|
||||||
|
|
||||||
|
int *incr_dicedigit(int *digits);
|
||||||
|
char **fetch_dict(char *dictfile);
|
||||||
|
|
||||||
|
#endif
|
||||||
124
tossing.c
Normal file
124
tossing.c
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tossing.h"
|
||||||
|
|
||||||
|
unsigned char *toss(int count) {
|
||||||
|
/*
|
||||||
|
toss <count> dices. if the global humandice is enabled (option -t),
|
||||||
|
then ask the human to toss dices and enter the numbers interactively.
|
||||||
|
otherwise generate tosses from /dev/random.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE *RAND;
|
||||||
|
int i;
|
||||||
|
int pos = 0;
|
||||||
|
uint8_t onedice;
|
||||||
|
unsigned char *tosses = NULL;
|
||||||
|
unsigned char *rand = NULL;
|
||||||
|
size_t len;
|
||||||
|
ssize_t linelen;
|
||||||
|
|
||||||
|
if(humantoss) {
|
||||||
|
char *line = NULL;
|
||||||
|
char digit[2];
|
||||||
|
digit[1] = '\0';
|
||||||
|
|
||||||
|
RETRY:
|
||||||
|
fprintf(stderr, "enter 5 digits, each between 1-6\n");
|
||||||
|
linelen = getline(&line, &len, stdin);
|
||||||
|
tosses = malloc((size_t)count);
|
||||||
|
|
||||||
|
if(linelen < 6) /* 5 digits max allowed */
|
||||||
|
goto RETRY;
|
||||||
|
|
||||||
|
for(i=0; i<count; i++) { /* only digits allowed */
|
||||||
|
if(isdigit(line[i]) == 0)
|
||||||
|
goto RETRY;
|
||||||
|
|
||||||
|
digit[0] = line[i];
|
||||||
|
onedice = atoi(digit);
|
||||||
|
|
||||||
|
if (onedice < 1 || onedice > 6) /* no dice digit */
|
||||||
|
goto RETRY;
|
||||||
|
|
||||||
|
tosses[i] = onedice;
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rand = malloc(RLEN);
|
||||||
|
|
||||||
|
if((RAND = fopen("/dev/urandom", "rb")) == NULL)
|
||||||
|
perror("Could not open /dev/urandom");
|
||||||
|
|
||||||
|
if(fread(rand, RLEN, 1, RAND) != 1)
|
||||||
|
perror("Could not read from /dev/urandom");
|
||||||
|
|
||||||
|
fclose(RAND);
|
||||||
|
|
||||||
|
tosses = malloc((size_t)count);
|
||||||
|
|
||||||
|
for(i=0; i<RLEN; i++) {
|
||||||
|
onedice = rand[i];
|
||||||
|
onedice &= 7; /* only use the last 3 bits, 0-7 */
|
||||||
|
onedice %= 6; /* 6 is the max */
|
||||||
|
if(onedice >= 1 && onedice <= 6) {
|
||||||
|
tosses[pos] = onedice;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
if(pos == count)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tosses;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rand_lim(int limit) {
|
||||||
|
/*
|
||||||
|
return a random number in the range [0..limit)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int divisor = RAND_MAX/limit;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
do {
|
||||||
|
retval = rand() / divisor;
|
||||||
|
} while (retval == limit);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int get_dicenum(int *digits) {
|
||||||
|
/*
|
||||||
|
get the actual number of an array of dice digits
|
||||||
|
*/
|
||||||
|
int i = 0;
|
||||||
|
int pos = 0;
|
||||||
|
for(i=0; i<5; i++)
|
||||||
|
pos += digits[i];
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
42
tossing.h
Normal file
42
tossing.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of dicepwgen
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 T.v.Dein.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* You can contact me by mail: <tom AT vondein DOT org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_TOSSING_H
|
||||||
|
#define HAVE_TOSSING_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define RLEN 1024
|
||||||
|
|
||||||
|
extern int humantoss;
|
||||||
|
extern int WMIN;
|
||||||
|
extern int WMAX;
|
||||||
|
|
||||||
|
unsigned char *toss(int count);
|
||||||
|
int rand_lim(int limit);
|
||||||
|
int get_dicenum(int *digits);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user