chiark / gitweb /
wordlist generator
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 4 Sep 2013 23:39:33 +0000 (00:39 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 4 Sep 2013 23:39:33 +0000 (00:39 +0100)
service

diff --git a/service b/service
index bbcc43be545476f9b9c1df406d163181382c7fe8..5b997bd1bf15fcf280ffd39fbe31d2a132824fe3 100755 (executable)
--- a/service
+++ b/service
@@ -9,6 +9,12 @@ options
   -h     (display help)
 options for alphanum generation
   -l<minrandlength>   (for create/choose alphanum, minimum randlength)
+options for wordlist generation
+  -Wf<wordlist>       (switches generation method to wordlist)
+  -WF<min-word-list-len>             } (for wordlist generation
+  -Wl<min-num-words>                 }   method only)
+  -WL<min-max-mean-word-len>         }
+  -Wd<permitted-delimiter-chars>     } (first char is default; comma = none)
 END
 our $usage2 = <<'END';
 actions
@@ -32,6 +38,12 @@ our %usage_genopts = (
 'alphanum' => <<END,
   -l<randlength>      (number of letters+digits)
 END
+'wordlist' => <<END,
+  -l<num-words>       (number of words in output)
+  -d<delim-char>      (delimiter character, "," means none)
+  -F<max-dict-size>   (pick from up to <dictsize> different words, 0 means all)
+  -m<max-addr-len>    (restrict total length of generated addrs, 0 = unlimited)
+END
 );
 #/
 
@@ -56,6 +68,20 @@ our $maxrandlength = 100;
 #   genopts
 our $randlength;
 
+# for wordlist
+#   options
+our $wordlist;
+our $minwordlistlen = 1000;
+our $minmaxmeanwordlen = 6.2;
+our $minnumwords = 3;
+our $maxnumwords = 10;
+our $worddelims = '.-_,';
+#   genopts
+our $numwords;
+our $worddelim;
+our $wordlistlen = 3000;
+our $maxdomainlen = 40;
+
 sub nextarg () {
     die "too few arguments\n" unless @ARGV;
     my $v = shift @ARGV;
@@ -221,6 +247,57 @@ sub gendefaults_alphanum {
     $randlength ||= $minrandlength;
 }
 
+sub gen_local_part_wordlist {
+    my @cmd = (qw(random-word), "-f$wordlist","-n$numwords");
+    push @cmd, "-F$wordlistlen" if $wordlistlen < 1e9;
+    for (;;) {
+       open P, "-|", @cmd or die $!;
+       my $s = <P>;
+       $!=0; $?=0; close P or die "$? $!";
+       chomp $s or die;
+       $s =~ s/ /$worddelim/g;
+       my $efflen = length $s;
+       $efflen += 1 + length($dom) if defined $dom;
+       return $s if $efflen <= $maxdomainlen;
+    }
+}
+
+sub genopt_wordlist {
+    local ($_) = @_;
+    if (m/^-l(\d+)$/) {
+       $numwords = $1;
+       die "length out of range $minnumwords..$maxnumwords\n"
+           unless ($minnumwords<=$numwords &&
+                   $numwords<=$maxnumwords);
+    } elsif (m/^-d(.)$/) {
+       $worddelim = $1;
+       die "word delimiter must be one of \`$worddelims'\n"
+           unless grep { $worddelim eq $_ } split //, $worddelims;
+    } elsif (m/^-F(\d+)$/) {
+       $wordlistlen = $1 ? 0+$1 : 1e9;
+       die "requested dictionary size too small\n"
+           unless $wordlistlen >= $minwordlistlen;
+    } elsif (m/^-m(\d+)$/) {
+       $maxdomainlen = $1 ? 0+$1 : 1e9;
+    } else {
+       die "unknown wordlist generation option\n";
+    }
+}
+
+sub gendefaults_wordlist {
+    $numwords ||= $minnumwords;
+    $worddelim = substr($worddelims,0,1) unless defined $worddelim;
+    $worddelim = '' if $worddelim eq ',';
+    my $expectedmindomlen =
+       (defined $dom ? (1 + length $dom) : 0) # @domain.name
+       + $minmaxmeanwordlen * $numwords # some words
+       + (length $worddelim) * ($numwords-1); # delimiters
+    die "assuming lowest reasonable mean word length $minmaxmeanwordlen".
+       " addrs would be $expectedmindomlen long but".
+       " your maximum length specified $maxdomainlen\n"
+       if $expectedmindomlen > $maxdomainlen;
+}
+
 sub genopts {
     while (@ARGV && $ARGV[0] =~ m/^-/) {
        my $arg = shift @ARGV;
@@ -411,11 +488,20 @@ while (@ARGV) {
            $dom = $1;
        } elsif (s/^-q(\S+)$//) {
            $qualdom = $1;
+       } elsif (s/^-Wf(\S+)$//) {
+           $wordlist = $1;
+           $genmethod = 'wordlist';
+       } elsif (s/^-WF(\d+)$//) {
+           $minwordlistlen = $1;
+       } elsif (s/^-Wl(\d+)$//) {
+           $minnumwords = $1;
+       } elsif (s/^-WL([0-9.]+)$//) {
+           $minmaxmeanwordlen = $1;
        } elsif (s/^-C/-/) {
            $showcomment = 1;
        } elsif (s/^-h/-/) {
            print $usage1.$usage2.$usage3 or die $!;
-           foreach my $meth (qw(alphanum)) {
+           foreach my $meth (qw(alphanum wordlist)) {
                print "genopts for $meth generation method\n" or die $!;
                print $usage_genopts{$meth} or die $!;
            }