Module: MemorableStrings::Extensions::String
- Defined in:
- lib/memorable_strings/extensions/string.rb
Overview
Adds support for easily generating memorable strings
Instance Method Summary collapse
-
#memorable(options = {}) ⇒ Object
Generates a string based on a set of rules defining which characters should be grouped together to form a memorable sequence.
Instance Method Details
#memorable(options = {}) ⇒ Object
Generates a string based on a set of rules defining which characters should be grouped together to form a memorable sequence.
Configuration options:
-
:length- The length of the string to generate. Default is 8. -
:capital- Whether to include a capital letter. Default is false. -
:digit- Whether to include a digit. Default is false. -
:print_friendly- Whether to only include characters that are unambiguous when printed out. This includes: B8G6I1l0OQDS5Z2
Examples
String.memorable # => "maikipeo"
String.memorable(:length => 5) # => "quoge"
String.memorable(:capital => true) # => "Bukievai"
String.memorable(:digit => true) # => "ood4yosa"
String.memorable(:capital => true, :digit => true) # => "Goodah5e"
Algorithm
See MemorableStrings::Consonant, MemorableStrings::Vowel, and MemorableStrings::Digit for more information about how it’s determined which characters are allowed to follow which other characters.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/memorable_strings/extensions/string.rb', line 33 def memorable( = {}) invalid_keys = .keys - [:length, :capital, :digit, :print_friendly] raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty? length = [:length] || 8 raise ArgumentError, 'Length must be at least 1' if length < 1 raise ArgumentError, 'Length must be at least 3 if using digits' if length < 3 && [:digit] value = nil conditions = lambda {|phoneme| [:print_friendly] ? phoneme.print_friendly?(:downcase) : true} begin value = '' stack = [] left = length flags = .dup phoneme = nil begin if !phoneme # Special-case first phoneme = Phoneme.first(left, &conditions) elsif flags[:digit] && stack.length >= 2 && rand(10) < 3 # Add digit in >= 3rd spot (30% chance) flags.delete(:digit) phoneme = Digit.random(1, &conditions) else # Choose next based on current phoneme phoneme = phoneme.next(stack, left, &conditions) end # Track the phoneme stack << phoneme value << phoneme.value left -= phoneme.length # Capitalize the first letter, phoneme after or a digit, or a consonant (30% chance) if flags[:capital] previous = stack[-2] upcase_allowed = ![:print_friendly] || phoneme.print_friendly?(:upcase) context_allowed = !previous || previous.is_a?(Digit) || phoneme.is_a?(Consonant) if upcase_allowed && context_allowed && rand(10) < 3 flags.delete(:capital) value[-phoneme.length, 1] = value[-phoneme.length, 1].upcase! end end end while left > 0 end while [:capital, :digit].any? {|key| flags.include?(key)} value end |