module Altpass
Constants
- AMBIGUOUS
- DEFAULT_LENGTH
- DEFAULT_OPTIONS
- LL
- LN
character sets divided by touch typing hands
- LU
- RL
- RN
- RU
- VERSION
Public Class Methods
generate(options={})
click to toggle source
return a password
# File lib/altpass.rb, line 28 def self.generate(options={}) options = self._verify_options(options) password = '' iterations = options[:length]/DEFAULT_LENGTH + 1 iterations.times { password += self._generate(options) } password.slice(0...options[:length]) end
permutations(options={})
click to toggle source
return the number of permutations, and additionally print out details when options contains v's
# File lib/altpass.rb, line 38 def self.permutations(options={}) options = self._verify_options(options) p = 1 pattern = options[:length].even? ? @pattern_even : @pattern_odd plen = pattern.length samples = [] (0...options[:length]).each { |i| samples[i] = (options[:memorizable] ? pattern[i%plen][0] : pattern[i%plen].flatten).reject{|c| AMBIGUOUS.include?(c)} p *= samples[i].length # take the product of all sample sizes to get the total number of permutations } if options[:permutations] =~ /^v{3,}\Z/ puts 'sample sets:' samples.each {|s| puts s.inspect } end puts "#{samples.collect {|s| s.length}.join(' * ')} permutations" if options[:permutations] =~ /^v{2,}\Z/ p end
Private Class Methods
_generate(options={})
click to toggle source
generate and return a string, having a parity-appropriate pattern, where each character is sampled from the appropriate character set (depending on whether :memorizable is true or false)
# File lib/altpass.rb, line 71 def self._generate(options={}) options = self._verify_options(options) pattern = options[:length].even? ? @pattern_even : @pattern_odd return pattern.collect { |i| s ='' loop do s = _sample(i[options[:memorizable] ? 0 : rand(i.length)]) break unless AMBIGUOUS.include?(s) end s }.join.slice(0..-1) end
_sample(a=[])
click to toggle source
pick a random element from the given array
# File lib/altpass.rb, line 85 def self._sample(a=[]) raise ArgumentError, "expected an Array, but got: #{a.class}" unless a.kind_of?(Array) raise ArgumentError, 'expected a non-empty Array, but got an empty one' unless a.length > 0 a[rand(a.length)] end
_verify_options(options=nil)
click to toggle source
verify and return an options hash, after merging the default options with the incoming ones
# File lib/altpass.rb, line 61 def self._verify_options(options=nil) raise ArgumentError, "expected a Hash, but got: #{options.inspect}" unless options.kind_of?(Hash) options = DEFAULT_OPTIONS.merge(options) raise ArgumentError, "expected :memorizable to be boolean, but got: #{options[:memorizable].inspect}" unless options[:memorizable].kind_of?(TrueClass) || options[:memorizable].kind_of?(FalseClass) raise ArgumentError, "expected :length to be an Integer, but got: #{options[:length].inspect}" unless options[:length].kind_of?(Integer) raise ArgumentError, "expected :length > 0, but got: #{options[:length]}" unless options[:length] > 0 options end