class PawGen
Constants
- AMBIGUOUS
- ANGLOCONSONANTS
- ANGLOPHONEMES
- ANGLOVOWELS
- DIGITS
- KANA_MORAE
Real kana includes signs to prolongate a preceding vowel or a following consonant. We're not including these, based on the wild-assed guess that the advantage in memorability is outweighed by the disadvantage in reduced password space.
Similarly, we're not indicating palatalisation: we'll use 'ti' rather than 'chi', 'tu' rather than 'tsu', and so on.
- LOWERCASE
- PHF_CONSONANT
Phoneme flags
- PHF_DIPTHONG
- PHF_NOT_FIRST
- PHF_VOWEL
- REQ_DIGITS
- REQ_SYMBOLS
- REQ_UPPERCASE
Requirement flags
- SYMBOLS
- UPPERCASE
- VOWELS
Attributes
length[R]
Public Class Methods
new()
click to toggle source
Calls superclass method
# File lib/pawgen.rb, line 11 def initialize super() # The original defaulted the length to 8, but it's a bit too # short to be the default length these days -- especially # considering that phonemic password construction shrinks # the password space. @length = 12 @include_uppercase = true @include_digits = true @include_symbols = false @exclude_ambiguous = false @exclude_vowels = false @mode = method :anglophonemic return end
random_bool(probability_of_true)
click to toggle source
# File lib/pawgen.rb, line 135 def self::random_bool probability_of_true return SecureRandom.random_number < probability_of_true end
random_item(array)
click to toggle source
# File lib/pawgen.rb, line 139 def self::random_item array return array[SecureRandom.random_number array.length] end
Public Instance Methods
anglophonemic()
click to toggle source
# File lib/pawgen.rb, line 223 def anglophonemic raise 'unable to generate such a ' + 'short anglophonemic password' \ unless length >= 5 raise 'unable to generate an ' + 'anglophonemic password with no vowels' \ if exclude_vowels? reqs = 0 reqs |= REQ_UPPERCASE if include_uppercase? reqs |= REQ_DIGITS if include_digits? reqs |= REQ_SYMBOLS if include_symbols? result, unmet_reqs = [] # declare local variables begin unmet_reqs = reqs first = true # also re-set after a digit (but not after a symbol) result = '' prev_phoneme_flags = 0 should_be = nil while result.length < length do should_be ||= PawGen.random_item [ANGLOVOWELS, ANGLOCONSONANTS] phoneme, phoneme_flags = PawGen.random_item should_be next if first and (phoneme_flags & PHF_NOT_FIRST) != 0 # block a vowel followed by a vowel-dipthong next if (prev_phoneme_flags & PHF_VOWEL) != 0 and (phoneme_flags & PHF_VOWEL) != 0 and (phoneme_flags & PHF_DIPTHONG) != 0 next if result.length + phoneme.length > length if include_uppercase? and (first or (phoneme_flags & PHF_CONSONANT) != 0) and PawGen.random_bool 0.2 then phoneme = phoneme.capitalize unmet_reqs &= ~REQ_UPPERCASE end # Note that the unambiguous lowercase 'o' can become the # ambiguous 'O' through capitalisation. Contrariwise, # the ambiguous lowercase 'l' can become the unambiguous # uppercase 'L'. next if exclude_ambiguous? and phoneme.split('').any?{|c| AMBIGUOUS.include? c} # All the checks for the phoneme passed. Let's add it. result << phoneme break if result.length == length # Checking against the [[first]] flag here means # requiring at least _two_ phonemes before the digit can # appear, because if we just applied the first phoneme, # [[first]] is still true. if include_digits? and !first and PawGen.random_bool 0.3 then choice = DIGITS.split '' choice -= AMBIGUOUS.split '' if exclude_ambiguous? result << PawGen.random_item(choice) unmet_reqs &= ~REQ_DIGITS first = true prev_phoneme_flags = 0 should_be = nil # pick next [[should_be]] at random next end if include_symbols? and !first and PawGen.random_bool 0.2 then choice = SYMBOLS.split '' # Our [[AMBIGUOUS]] does not actually contain any # symbols in the current version. This may be a # problem, considering [['`]] and [[!/1l|]] and [[&8]] # and [[-_]] and [[^~]] and maybe even [[.,]] and # [[:;]] and [[()l|]] so we're excluding [[AMBIGUOUS]] # anyway in anticipation of a future version # mentioning some of those. choice -= AMBIGUOUS.split '' if exclude_ambiguous? result << PawGen.random_item(choice) unmet_reqs &= ~REQ_SYMBOLS # not resetting [[first]]; not [[next]]ing end if should_be.object_id == ANGLOCONSONANTS.object_id then should_be = ANGLOVOWELS else if (prev_phoneme_flags & PHF_VOWEL) != 0 or (phoneme_flags & PHF_DIPTHONG) != 0 or PawGen.random_bool(0.6) then should_be = ANGLOCONSONANTS else should_be = ANGLOVOWELS end end prev_phoneme_flags = phoneme_flags first = false end end until unmet_reqs.zero? return result end
do_not_exclude_ambiguous!()
click to toggle source
# File lib/pawgen.rb, line 78 def do_not_exclude_ambiguous! @exclude_ambiguous = false return self end
Also aliased as: dont_exclude_ambiguous!
do_not_exclude_vowels!()
click to toggle source
# File lib/pawgen.rb, line 95 def do_not_exclude_vowels! @exclude_vowels = false return self end
Also aliased as: dont_exclude_vowels!
exclude_ambiguous!()
click to toggle source
# File lib/pawgen.rb, line 73 def exclude_ambiguous! @exclude_ambiguous = true return self end
exclude_ambiguous?()
click to toggle source
# File lib/pawgen.rb, line 69 def exclude_ambiguous? return @exclude_ambiguous end
exclude_vowels!()
click to toggle source
# File lib/pawgen.rb, line 90 def exclude_vowels! @exclude_vowels = true return self end
exclude_vowels?()
click to toggle source
# File lib/pawgen.rb, line 86 def exclude_vowels? return @exclude_vowels end
generate()
click to toggle source
# File lib/pawgen.rb, line 131 def generate return @mode.call end
include_digits!()
click to toggle source
# File lib/pawgen.rb, line 45 def include_digits! @include_digits = true return self end
include_digits?()
click to toggle source
# File lib/pawgen.rb, line 41 def include_digits? return @include_digits end
include_symbols!()
click to toggle source
# File lib/pawgen.rb, line 59 def include_symbols! @include_symbols = true return self end
include_symbols?()
click to toggle source
# File lib/pawgen.rb, line 55 def include_symbols? return @include_symbols end
include_uppercase!()
click to toggle source
# File lib/pawgen.rb, line 31 def include_uppercase! @include_uppercase = true return self end
include_uppercase?()
click to toggle source
# File lib/pawgen.rb, line 27 def include_uppercase? return @include_uppercase end
kanaphonemic()
click to toggle source
# File lib/pawgen.rb, line 338 def kanaphonemic raise 'unable to generate such a ' + 'short kanaphonemic password' \ unless length >= 5 raise 'unable to generate an ' + 'kanaphonemic password with no vowels' \ if exclude_vowels? reqs = 0 reqs |= REQ_UPPERCASE if include_uppercase? reqs |= REQ_DIGITS if include_digits? reqs |= REQ_SYMBOLS if include_symbols? result, unmet_reqs = [] # declare local variables begin unmet_reqs = reqs first = true # also re-set after a digit (but not after a symbol) result = '' while result.length < length do phoneme = PawGen.random_item KANA_MORAE next if result.length + phoneme.length > length if include_uppercase? and PawGen.random_bool 0.2 then phoneme = phoneme.capitalize unmet_reqs &= ~REQ_UPPERCASE end # Note that the unambiguous lowercase 'o' can become the # ambiguous 'O' through capitalisation. next if exclude_ambiguous? and phoneme.split('').any?{|c| AMBIGUOUS.include? c} # All the checks for the phoneme passed. Let's add it. result << phoneme break if result.length == length # Checking against the [[first]] flag here means # requiring at least _two_ phonemes before the digit can # appear, because if we just applied the first phoneme, # [[first]] is still true. if include_digits? and !first and PawGen.random_bool 0.3 then choice = DIGITS.split '' choice -= AMBIGUOUS.split '' if exclude_ambiguous? result << PawGen.random_item(choice) unmet_reqs &= ~REQ_DIGITS first = true next end if include_symbols? and !first and PawGen.random_bool 0.2 then choice = SYMBOLS # Our [[AMBIGUOUS]] does not actually contain any # symbols in the current version. This may be a # problem, considering [['`]] and [[!/1l|]] and [[&8]] # and [[-_]] and [[^~]] and maybe even [[.,]] and # [[:;]] and [[()l|]] so we're excluding [[AMBIGUOUS]] # anyway in anticipation of a future version # mentioning some of those. choice -= AMBIGUOUS.split '' if exclude_ambiguous? result << PawGen.random_item(choice) unmet_reqs &= ~REQ_SYMBOLS # not resetting [[first]]; not [[next]]ing end first = false end end until unmet_reqs.zero? return result end
length=(new_length)
click to toggle source
# File lib/pawgen.rb, line 104 def length= new_length set_length! new_length return new_length end
no_digits!()
click to toggle source
# File lib/pawgen.rb, line 50 def no_digits! @include_digits = false return self end
no_symbols!()
click to toggle source
# File lib/pawgen.rb, line 64 def no_symbols! @include_symbols = false return self end
no_uppercase!()
click to toggle source
# File lib/pawgen.rb, line 36 def no_uppercase! @include_uppercase = false return self end
set_length!(new_length)
click to toggle source
# File lib/pawgen.rb, line 109 def set_length! new_length raise 'invalid length' \ unless new_length.is_a? Integer and new_length >= 1 @length = new_length return self end
structureless()
click to toggle source
# File lib/pawgen.rb, line 143 def structureless charset = LOWERCASE charset += UPPERCASE if include_uppercase? charset += DIGITS if include_digits? charset += SYMBOLS if include_symbols? charset = charset.split('') charset -= AMBIGUOUS.split('') if exclude_ambiguous? charset -= VOWELS.split('') if exclude_vowels? return (0 ... @length). map{PawGen.random_item charset}. join '' end
use_anglophonemic_generator!()
click to toggle source
# File lib/pawgen.rb, line 121 def use_anglophonemic_generator! @mode = method :anglophonemic return end
use_kanaphonemic_generator!()
click to toggle source
# File lib/pawgen.rb, line 126 def use_kanaphonemic_generator! @mode = method :kanaphonemic return end
use_structureless_generator!()
click to toggle source
# File lib/pawgen.rb, line 116 def use_structureless_generator! @mode = method :structureless return end