Skip to content

Instantly share code, notes, and snippets.

@sbeam
Created March 15, 2012 02:03
Show Gist options
  • Save sbeam/2041198 to your computer and use it in GitHub Desktop.
Save sbeam/2041198 to your computer and use it in GitHub Desktop.
password/passphrase hybrid generator
#!/usr/bin/perl -w
# Usage: randpw.pl <len>
# optional <len> truncate to so many chars
# using my copy of /usr/dict/words, n = 53970, so with default settings, r=2 and
# ((n+1)! / (r * (n-1)!) = 1456407435 (because its a duplicative combination at this stage)
# so there are
# (1456407435 * 1000 * 68)^3 = 9.7134 x 10^41
# possible passwords here,
# or
# ~139 bits of entropy. Not too shabby.
# http://en.wikipedia.org/wiki/Password_strength
#
# actual output:
# $ randpw-weak 16
# Gripped + Unnerving
# vUnnerving581Gripped
# Unnerving581Grip
#
# Author: sbeam
# License: DWTFYW
my $dict = "/usr/share/dict/words";
my $maxlen = shift @ARGV;
my $wordmin = 2;
my $wordmax = 9;
my $num_words = 2;
my $skip_possessives = 1; # db contains 's forms for every noun
use List::Util qw(shuffle);
srand;
open(WORDS, $dict) or die($!);
# two random words from dict
my $shorts = 0;
my @parts;
while (<WORDS>) {
chop;
next if (/'s$/ && $skip_possessives);
if (length() >= $wordmin and length() <= $wordmax) {
$shorts++;
for ($i=0; $i<$num_words; $i++) {
(rand($shorts) < 1) && ($parts[$i] = ((rand(2)<1)? ucfirst($_) : $_) );
}
}
}
print join(' + ', @parts) . "\n";
# a random number 0 - 1000
push(@parts, sprintf('%d', rand(1000)));
# one of these thingys, for extra l33tness
my @chars=('a'..'z','A'..'Z','0'..'9','_','-','/','+','$','@');
push(@parts, $chars[rand @chars]);
# stir and serve chilled.
my $whole = join('', shuffle @parts);
print "$whole\n";
if ($maxlen && $maxlen < length($whole)) {
$whole = substr($whole, rand(length($whole)-$maxlen), $maxlen);
print "$whole\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment