Skip to content

Instantly share code, notes, and snippets.

@preetpalS
Last active November 16, 2018 14:23
Show Gist options
  • Save preetpalS/b502659b9cb2ddd80fce33932c5dd047 to your computer and use it in GitHub Desktop.
Save preetpalS/b502659b9cb2ddd80fce33932c5dd047 to your computer and use it in GitHub Desktop.
Simple command line random password generator (Ruby)
#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
class RandomPasswordGenerator
VERSION = %w(0.1.0)
CORE_CHARACTER_SET = [('a'..'z').to_a,
('A'..'Z').to_a,
(0..9).map(&:to_s)].flatten.freeze
BASIC_SYMBOL_SET = ['$', '_', '-', '+', '='].freeze
BASIC_SYMBOL_SET_KEY = 'basic'
EMPTY_SYMBOL_SET = [].freeze
EMPTY_SYMBOL_SET_KEY = 'empty'
FULL_SYMBOL_SET = # Higher chance of experiencing compatibility issues
['`', '~', '!', '@', '#', '$', '%', '^',
'&', '*', '(', ')', '_', '-', '=', '+',
'[', ']', '{', '}', '\\', '|', ':', ';',
'\'', '"', ',', '.', '<', '>', '/', '?'].freeze
FULL_SYMBOL_SET_KEY = 'full'
SYMBOL_SETS = [BASIC_SYMBOL_SET_KEY, EMPTY_SYMBOL_SET_KEY, FULL_SYMBOL_SET_KEY].freeze
SYMBOL_SET_ALIASES = SYMBOL_SETS.map { |s| [s[0], s] }.to_h.freeze
SYMBOL_SET_MAX_KEY_LENGTH = SYMBOL_SETS.map(&:length).max
DEFAULT_SYMBOL_SET_KEY = BASIC_SYMBOL_SET_KEY
DEFAULT_MINIMUM_LENGTH = 12
DEFAULT_MAXIMUM_LENGTH = 25
def initialize
# Note that the standard library OptionParser library invoked in the following method has access
# to ARGV and removes any options that it found and parsed in ARGV (argument vector).
@options = parse_command_line_arguments
puts generate_random_password
end
private
def parse_command_line_arguments
options = OpenStruct.new
options.symbol_set = DEFAULT_SYMBOL_SET_KEY
options.minimum_length = DEFAULT_MINIMUM_LENGTH
options.maximum_length = DEFAULT_MAXIMUM_LENGTH
OptionParser.new do |opts|
opts.banner = 'Usage: random_password_generator [options]'
opts.separator ''
opts.separator 'Specific options:'
opts.on('-sSYMBOL_SET', '--symbol-set=SYMBOL_SET', SYMBOL_SETS, SYMBOL_SET_ALIASES,
<<MESSAGE) do |symbol_set|
Select which symbol-set to use from the following (default=#{DEFAULT_SYMBOL_SET_KEY}):
#{BASIC_SYMBOL_SET_KEY.ljust(SYMBOL_SET_MAX_KEY_LENGTH)}\t\t#{BASIC_SYMBOL_SET.join(' ')}
#{EMPTY_SYMBOL_SET_KEY}
#{FULL_SYMBOL_SET_KEY.ljust(SYMBOL_SET_MAX_KEY_LENGTH)}\t\t#{FULL_SYMBOL_SET.join(' ')}
MESSAGE
options.symbol_set = symbol_set
end
opts.on('--minimum-length=MIN',
"Set minimum length of generated random password (default=#{DEFAULT_MINIMUM_LENGTH})") do |minimum_length|
options.minimum_length = Integer(minimum_length)
end
opts.on('--maximum-length=MAX',
"Set maximum length of generated random password (default=#{DEFAULT_MAXIMUM_LENGTH})") do |maximum_length|
options.maximum_length = Integer(maximum_length)
end
opts.separator ''
opts.separator 'Common options:'
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit
end
opts.on_tail('-v', '--version', 'Show version') do
puts "Version: #{VERSION.join('.')}"
exit
end
end.parse!
check_option_invariants(options)
options
end
def check_option_invariants(options)
fail "Program invariant violated (maximum_length cannot be less than minimum length)" if options.maximum_length < options.minimum_length
end
def symbol_set
case @options.symbol_set
when BASIC_SYMBOL_SET_KEY
BASIC_SYMBOL_SET
when EMPTY_SYMBOL_SET_KEY
EMPTY_SYMBOL_SET
when FULL_SYMBOL_SET_KEY
FULL_SYMBOL_SET
else
fail "Program invariant violated (unknown symbol set: ). GUID: e9ab3fd0-c17e-41da-a72a-a68855a253a0"
end
end
def acceptable_characters
@acceptable_characters ||= [
CORE_CHARACTER_SET,
symbol_set
].flatten.freeze
end
def generate_random_password
password_length = ((@options.minimum_length)..(@options.maximum_length)).to_a.sample
Array.new(password_length, nil).to_a.map { |_| acceptable_characters.sample }.join('')
end
end
RandomPasswordGenerator.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment