A Ruby script for generating sequential passwords to pipe into other tools. Supports command-line parameters to customize the password length range, character set, and password seed. Generated passwords are output to stdout.
> generator.rb -h
Password Generator
Usage: generator.rb [options]
-v, –verbose Output more information
-l, –lowercase Include lowercase letters in seeds
-u, –uppercase Include uppercase letters in seeds
-n, –numbers Include numbers in seeds
-s, –special Include special characters in seeds
-a, –all Include all characters in seeds
-m, –min NUMBER Set minimum seed length(>0)
-M, –max NUMBER Set maximum seed length(>minimum)
-w, –wifi Set min and max to acceptable wifi seed length
-S, –seed SEED Set starting seed string
-h, –help Display this screen
While running, press spacebar
to output generator stats to stderr.
#!/usr/bin/env ruby
require 'optparse'
require 'io/wait'
$interrupted = false
trap("INT") { $interrupted = true}
options = {}
optparse = OptionParser.new do |opts|
opts.banner = "Password Generator\nUsage: generator.rb [options]"
#Defines the command line options
options[:verbose] = false
opts.on('-v','--verbose', 'Output more information') do
options[:verbose] = true
end
options[:lowercase] = false
opts.on('-l', '--lowercase', 'Include lowercase letters in seeds') do
options[:lowercase] = true
end
options[:uppercase] = false
opts.on('-u', '--uppercase', 'Include uppercase letters in seeds') do
options[:uppercase] = true
end
options[:numbers] = false
opts.on('-n', '--numbers', 'Include numbers in seeds') do
options[:numbers] = true
end
options[:special] = false
opts.on('-s', '--special', 'Include special characters in seeds') do
options[:special] = true
end
options[:all] = false
opts.on('-a', '--all', 'Include all characters in seeds') do
options[:all] = true
options[:lowercase] = true
options[:uppercase] = true
options[:numbers] = true
options[:special] = true
end
options[:min] = 1
opts.on('-m NUMBER', '--min NUMBER', 'Set minimum seed length(>0)') do |i|
if i.to_i > 0
options[:min] = i.to_i
else
puts "Invalid Mimimum, must be greater than 0."
exit
end
end
options[:max] = 10
opts.on('-M NUMBER', '--max NUMBER', 'Set maximum seed length(>minimum)') do |i|
if i.to_i >= options[:min]
options[:max] = i.to_i
else
puts "Invalid Maximum, must be greater than or equal to the minimum."
exit
end
end
options[:wifi] = false
opts.on('-w', '--wifi', 'Set min and max to acceptable wifi seed length') do
options[:min] = 8
options[:max] = 63
end
options[:seed] = ""
opts.on('-S SEED', '--seed SEED', 'Set starting seed string') do |i|
options[:seed] = i
puts "Start seed: " + options[:seed]
end
opts.on('-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
optparse.parse!
#lowercase = "abcdefghijklmnopqrstuvwxyz"
lowercase = "etaoinsrhdlucmfywgpbvkxqjz"
#uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
uppercase = "ETAOINSRHDLUCMFYWGPBVKXQJZ"
numbers = "1234567890"
special = "\-\=\`\~\!\@\#$\%\^\&\*\(\)\_\+\,\.\/\<\>\?\;\'\:\"\[\]\{\}\\"
total = 0
$seeder = ""
$seeder = lowercase if options[:lowercase] == true
$seeder += uppercase if options[:uppercase]
$seeder += numbers if options[:numbers]
$seeder += special if options[:special]
$start_seed = (options[:seed].length >0 ? options[:seed] : "")
0.upto($start_seed.length-1) {|i|
if $seeder.index($start_seed[i]).nil?
puts "Seed character (" + $start_seed[i].chr + ") not in character set, please specify additional character sets."
exit
end
}
$seeder_length = $seeder.length
#puts $seeder
if $seeder_length == 0
puts "Must specify characters to use. See --help for available options."
exit
end
#puts $seeder
$start_time = Time.new
$max_length = options[:max]
$current_length = options[:min]
$current_slot = 0
$candidates = []
$password = ""
$total = 0
def initialize_candidates
0.upto($max_length-1) {|i| $candidates[i] = 0}
if $start_seed.length > 0
0.upto($start_seed.length-1) {|i| $candidates[i] = $seeder.index($start_seed[i])}
end
end
def increment_letter
$candidates[$current_slot] += 1
if $candidates[$current_slot] >= $seeder_length && $current_slot > 0
$candidates[$current_slot] = 0
$current_slot -= 1
increment_letter
end
end
def input?
begin
c = $stdin.getc
return true if c == "q"
show_stats if c == " "
false
rescue Errno::EINTR
false
rescue Errno::EAGAIN
false
rescue EOFError
true
end
end
def show_stats
$stderr.puts "Generator Stats - words: " + $total.to_s + " current: " + $password + " w/s: " + ($total/(Time.now - $start_time)).round.to_s + " run time: " + (Time.new - $start_time).to_i.to_s + " second(s)"#Time.new(Time.now - $start_time).strftime("%T")
end
def exiting
show_stats
$stderr.puts "Exiting... "
exit
end
#system("stty raw -echo")
initialize_candidates
#Curses.noecho
while $current_length <= $max_length
$password = ""
$current_slot = $current_length-1
0.upto($current_length-1) {|i| $password = $password + $seeder[$candidates[i]].chr}
$stdout.puts $password
$total += 1
increment_letter
if $candidates[0] >= $seeder_length
$current_length += 1
initialize_candidates
end
exiting if input? if $stdin.ready?#input?
exiting if $interrupted == true
end