PERL   54

genpass

Guest on 22nd September 2022 12:32:30 AM

  1. #!/usr/bin/perl -w
  2. # genpass - Flexible password generator
  3. #       Created by Brian Katzung, Kappa Computer Solutions, LLC.               
  4. #
  5. # This software has been placed in the public domain by the author.
  6. # This software is supplied without warranty of merchantability or fitness
  7. # for any purpose. Use at your own risk.
  8. #
  9. # Parameters:
  10. # a[$min]       Include (at least $min) lowercase letters
  11. # A[$min]       Include (at least $min) uppercase letters
  12. # 0[$min] or d[$min]
  13. #               Include (at least $min) decimal digits
  14. # h[$min]       Include (at least $min) lowercase hexadecimal digits
  15. # H[$min]       Include (at least $min) uppercase hexadecimal digits
  16. # '['$chars']'[$min]
  17. #               Include (at least $min) from listed $chars (ranges OK)
  18. # $length       Make passwords exactly $length characters long
  19. # $min-$max     Make passwords between $min and $max characters long
  20. # x$count       Generate $count passwords
  21.  
  22. use strict;
  23. use List::Util 'shuffle';
  24.  
  25. # Minimum and maximum password length
  26. my ($min_len, $max_len) = (16, 16);
  27. my $num_pas = 1;        # Number of passwords to generate
  28. my @sets;               # Character sets to use for password composition
  29.  
  30. ######################################################################
  31. # Functions
  32.  
  33. #
  34. # Return a random character from a character set
  35. #
  36. sub get_char {
  37.     my ($set) = @_;
  38.  
  39.     return $set->[int(rand(scalar @$set))];
  40. }
  41.  
  42. #
  43. # Generate character set ranges
  44. #
  45. sub get_charset {
  46.     my ($str) = @_;
  47.     my @parts = split(/(.-.)/, $str);
  48.     my @set = ();
  49.  
  50.     foreach (@parts) {
  51.         if (/^(.)-(.)$/) {
  52.             push(@set, $1 .. $2);
  53.         } elsif (length) {
  54.             push(@set, split(//));
  55.         }
  56.     }
  57.  
  58.     return \@set;
  59. }
  60.  
  61. #
  62. # Generate a password
  63. #
  64. sub gen_password {
  65.     my @chars;
  66.     my @combined = ();
  67.  
  68.     foreach (@sets) {
  69.         for (my $i = 0; $i < $_->[0]; ++$i) {
  70.             push(@chars, get_char($_->[1]));
  71.         }
  72.         push(@combined, @{$_->[1]});
  73.     }
  74.  
  75.     my $len = $min_len + int(rand($max_len - $min_len + 1));
  76.  
  77.     while (@chars < $len) {
  78.         push(@chars, get_char(\@combined));
  79.     }
  80.  
  81.     print shuffle(@chars), "\n";
  82. }
  83.  
  84. ######################################################################
  85. # Main program
  86.  
  87. #
  88. # Process arguments to choose character sets and quantities
  89. #
  90. foreach (@ARGV) {
  91.     my $min;
  92.  
  93.     if (/^a(\d*)/) {                            # lower alpha
  94.         $min = $1 || 1;
  95.         push(@sets, [ $min, [ 'a' .. 'z' ] ]);
  96.     } elsif (/^x(\d+)/) {                       # # of passwords
  97.         $num_pas = $1;
  98.     } elsif (/^A(\d*)/) {                       # upper alpha
  99.         $min = 0 + "0$1";
  100.         push(@sets, [ $min, [ 'A' .. 'Z' ] ]);
  101.     } elsif (/^[0d](\d*)/) {                    # numeric/decimal
  102.         $min = 0 + "0$1";
  103.         push(@sets, [ $min, [ '0' .. '9' ] ]);
  104.     } elsif (/^h(\d*)/) {                       # hexadecimal (lower)
  105.         $min = 0 + "0$1";
  106.         push(@sets, [ $min, [ '0' .. '9', 'a' .. 'f' ] ]);
  107.     } elsif (/^H(\d*)/) {                       # hexadecimal (upper)
  108.         $min = 0 + "0$1";
  109.         push(@sets, [ $min, [ '0' .. '9', 'A' .. 'F' ] ]);
  110.     } elsif (/^\[(.*)\](\d*)$/) {               # specific charset
  111.         $min = 0 + "0$2";
  112.         #push(@sets, [ $min, [ split(//, $1) ] ]);
  113.         push(@sets, [ $min, get_charset($1) ]);
  114.     } elsif (/^(\d+)(?:-(\d+))?/) {             # min/max length
  115.         $min_len = $1;
  116.         $max_len = $2 || $min_len;
  117.     }
  118. }
  119.  
  120. #
  121. # Check usage
  122. #
  123. if (!@sets) {
  124.     print "usage: $0 [a[min]] [A[min]] [0[min]] [h[min]] [H[min]]\n",
  125.       "\t[[charset][min]] [min[-max]] [xcount]\n";
  126.     exit 1;
  127. }
  128.  
  129. #
  130. # Generate passwords
  131. #
  132. for (my $i = 0; $i < $num_pas; ++$i) {
  133.     gen_password();
  134. }
  135.  
  136. # END

Raw Paste


Login or Register to edit or fork this paste. It's free.