Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2016
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.90 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use POSIX;
  4.  
  5. # Generates a random passphrase from dictionary words.
  6. # Free to use without license or restrictions.
  7.  
  8. sub usage
  9. {
  10.     warn "Arguments: [--entropy n]\n";
  11.     exit 1;
  12. }
  13.  
  14. my $entropy = 80; # bits of entropy in generated password
  15.  
  16. if (2 == @ARGV)
  17. {
  18.     usage if ("--entropy" ne $ARGV[0] && $ARGV[1] !~ /^[0-9]+$/);
  19.  
  20.     my $e = $ARGV[1] * 1;
  21.  
  22.     if ($e < $entropy)
  23.     {
  24.         warn "Entropy must be a minimum of $entropy.\n";
  25.         exit 1;
  26.     }
  27.  
  28.     $entropy = $e;
  29. }
  30. elsif (0 != @ARGV)
  31. {
  32.     usage;
  33. }
  34.  
  35. my $MIN = 4;
  36. my $MAX = 8;
  37. my $MIN_DICT = 30000;
  38.  
  39. my $wordsfile;
  40.  
  41. open $wordsfile, '<', "/usr/share/dict/words" or
  42. open $wordsfile, '<', "/usr/dict/words" or
  43. die "Could not open words file.";
  44.  
  45. my %words_hash = ();
  46.  
  47. while (<$wordsfile>)
  48. {
  49.     $_ =~ s/'.*//g;
  50.     $_ =~ s/[^a-zA-Z]//g;
  51.  
  52.     $_ = lc $_;
  53.  
  54.     $words_hash{$_} = 1 if (length ($_) >= $MIN and length ($_) <= $MAX);
  55. }
  56.  
  57. my @words = keys %words_hash;
  58.  
  59. close $wordsfile or warn $!;
  60.  
  61. die "Not enough words in dictionary." if (@words < $MIN_DICT);
  62.  
  63. my $entropy_per_word = log (@words) / log (2);
  64.  
  65. my $pw = "";
  66. my $pw_entropy = 0;
  67.  
  68. open my $random_source, '<', "/dev/urandom"
  69. or die "Could not open /dev/urandom";
  70.  
  71. binmode $random_source or die $!;
  72.  
  73. my $random_buffer = "";
  74.  
  75. my $random_bytes = ceil ($entropy_per_word / 8);
  76.  
  77. die "Tried to read no random bytes." if ($random_bytes < 1);
  78.  
  79. while ($pw_entropy < $entropy)
  80. {
  81.     die "Could not read random bytes"
  82.     if ($random_bytes !=
  83.         read ($random_source, $random_buffer, $random_bytes));
  84.  
  85.     my @bytes = unpack 'C ' x $random_bytes, $random_buffer;
  86.  
  87.     my $n = 0;
  88.  
  89.     foreach (@bytes)
  90.     {
  91.         $n *= 256;
  92.         $n += $_ * 1;
  93.     }
  94.  
  95.     next if ($n >= @words); # don't use %, it will bias the randomness
  96.  
  97.     $pw .= ' ' if ("" ne $pw);
  98.  
  99.     foreach (split //, $words[$n])
  100.     {
  101.         $_ = uc if (rand > 0.8);
  102.  
  103.         $pw .= $_;
  104.     }
  105.  
  106.     $pw_entropy += $entropy_per_word;
  107. }
  108.  
  109. print $pw;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement