Class: PassForge::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/passforge/generator.rb

Overview

Main password generator class Handles random password generation with customizable character sets

Class Method Summary collapse

Class Method Details

.build_charset(upper_case, lower_case, numbers, symbols) ⇒ Object

Build character set based on options



47
48
49
50
51
52
53
54
# File 'lib/passforge/generator.rb', line 47

def self.build_charset(upper_case, lower_case, numbers, symbols)
  charset = []
  charset += Charsets::UPPER_CASE if upper_case
  charset += Charsets::LOWER_CASE if lower_case
  charset += Charsets::NUMBERS if numbers
  charset += Charsets::SYMBOLS if symbols
  charset
end

.generate(length = 12, upper_case: true, lower_case: true, numbers: true, symbols: false, known_keywords: "", mix: true) ⇒ String

Generate a random password

Examples:

Generate a basic password

PassForge::Generator.generate(16)
# => "aB3dE7gH9jK2mN5p"

Generate a password with symbols

PassForge::Generator.generate(12, symbols: true)
# => "aB3!dE7@gH9#"

Generate a password with keywords

PassForge::Generator.generate(12, known_keywords: "dog,cat,fish", mix: true)
# => "dog3aB7gH9jK"

Parameters:

  • length (Integer) (defaults to: 12)

    Length of the password (default: 12)

  • upper_case (Boolean) (defaults to: true)

    Include uppercase letters (default: true)

  • lower_case (Boolean) (defaults to: true)

    Include lowercase letters (default: true)

  • numbers (Boolean) (defaults to: true)

    Include numbers (default: true)

  • symbols (Boolean) (defaults to: false)

    Include symbols (default: false)

  • known_keywords (String) (defaults to: "")

    Comma-separated keywords to include (default: “”)

  • mix (Boolean) (defaults to: true)

    Mix keywords with random characters (default: true)

Returns:

  • (String)

    Generated password

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/passforge/generator.rb', line 32

def self.generate(length = 12, upper_case: true, lower_case: true, numbers: true, symbols: false, known_keywords: "", mix: true)
  charset = build_charset(upper_case, lower_case, numbers, symbols)
  raise ArgumentError, "At least one character set must be enabled" if charset.empty? && known_keywords.empty?

  if mix && !known_keywords.empty?
    generate_mixed_password(length, charset, known_keywords)
  elsif !known_keywords.empty?
    generate_keyword_only_password(length, known_keywords, charset)
  else
    generate_random_password(length, charset)
  end
end

.generate_keyword_only_password(length, known_keywords, _charset) ⇒ Object

Generate password using only keywords



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/passforge/generator.rb', line 72

def self.generate_keyword_only_password(length, known_keywords, _charset)
  keywords_array = known_keywords.split(",")
  password = []
  remaining_length = length

  while remaining_length.positive?
    keyword = keywords_array.select { |k| k.length <= remaining_length }.sample

    if keyword.nil?
      # If no keyword fits exactly, fill the remaining space with parts of keywords
      keyword = keywords_array.sample
      keyword_part = keyword[0, remaining_length]
      password.concat(keyword_part.chars)
      remaining_length -= keyword_part.length
    else
      password.concat(keyword.chars)
      remaining_length -= keyword.length
    end
  end

  # If the password is shorter than the required length, fill with additional keyword parts
  while password.length < length
    keyword = keywords_array.sample
    remaining_length = length - password.length
    password.concat(keyword[0, remaining_length].chars)
  end

  password.join
end

.generate_mixed_password(length, charset, known_keywords) ⇒ Object

Generate password with keywords mixed with random characters



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/passforge/generator.rb', line 58

def self.generate_mixed_password(length, charset, known_keywords)
  password = Array.new(length) { charset.sample }

  keywords_array = known_keywords.split(",")
  keyword = keywords_array.sample
  keyword_length = keyword.length
  keyword_pos = SecureRandom.random_number(length - keyword_length + 1)
  password[keyword_pos, keyword_length] = keyword.chars

  password.join
end

.generate_random_password(length, charset) ⇒ Object

Generate completely random password



104
105
106
# File 'lib/passforge/generator.rb', line 104

def self.generate_random_password(length, charset)
  Array.new(length) { charset.sample }.join
end