Class: PseudoRandom::Generator

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

Constant Summary collapse

ALPHABETIC_CHARS =

Character set for alphabetic generation: A-Z (26) + a-z (26) = 52 characters

('A'..'Z').to_a + ('a'..'z').to_a
ALPHANUMERIC_CHARS =

Character set for alphanumeric generation: A-Z (26) + a-z (26) + 0-9 (10) = 62 characters

('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a

Instance Method Summary collapse

Constructor Details

#initialize(seed = nil) ⇒ Generator

Returns a new instance of Generator.



23
24
25
# File 'lib/pseudo_random.rb', line 23

def initialize(seed = nil)
  @random = Random.new(normalize_seed(seed))
end

Instance Method Details

#alphabetic(length) ⇒ String

Generates an alphabetic string with the specified number of characters

Parameters:

  • length (Integer)

    the number of alphabetic characters to generate (must be >= 0)

Returns:

  • (String)

    a string containing uppercase letters (A-Z) and lowercase letters (a-z)

Raises:

  • (ArgumentError)


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
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/pseudo_random.rb', line 72

def alphabetic(length)
  raise ArgumentError, 'Length must be a non-negative integer' unless length.is_a?(Integer) && length >= 0

  return '' if length == 0

  result = ''
  remaining = length

  # Process multiple characters at once for efficiency
  # We can generate about 3 characters from a 32-bit random number (52^3 = 140,608 < 2^32)
  chunk_size = 3

  while remaining >= chunk_size
    # Generate a random number and convert to base-52 representation
    random_value = @random.rand(52**chunk_size)
    chunk = ''

    chunk_size.times do
      chunk = ALPHABETIC_CHARS[random_value % 52] + chunk
      random_value /= 52
    end

    result += chunk
    remaining -= chunk_size
  end

  # Process remaining characters (1-2)
  if remaining > 0
    random_value = @random.rand(52**remaining)
    chunk = ''

    remaining.times do
      chunk = ALPHABETIC_CHARS[random_value % 52] + chunk
      random_value /= 52
    end

    result += chunk
  end

  result
end

#alphanumeric(length) ⇒ String

Generates an alphanumeric string with the specified number of characters

Parameters:

  • length (Integer)

    the number of alphanumeric characters to generate (must be >= 0)

Returns:

  • (String)

    a string containing uppercase letters (A-Z), lowercase letters (a-z), and digits (0-9)

Raises:

  • (ArgumentError)


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/pseudo_random.rb', line 117

def alphanumeric(length)
  raise ArgumentError, 'Length must be a non-negative integer' unless length.is_a?(Integer) && length >= 0

  return '' if length == 0

  result = ''
  remaining = length

  # Process multiple characters at once for efficiency
  # We can generate about 5 characters from a 32-bit random number (62^5 = 916,132,832 < 2^32)
  chunk_size = 5

  while remaining >= chunk_size
    # Generate a random number and convert to base-62 representation
    random_value = @random.rand(62**chunk_size)
    chunk = ''

    chunk_size.times do
      chunk = ALPHANUMERIC_CHARS[random_value % 62] + chunk
      random_value /= 62
    end

    result += chunk
    remaining -= chunk_size
  end

  # Process remaining characters (1-4)
  if remaining > 0
    random_value = @random.rand(62**remaining)
    chunk = ''

    remaining.times do
      chunk = ALPHANUMERIC_CHARS[random_value % 62] + chunk
      random_value /= 62
    end

    result += chunk
  end

  result
end

#hex(length) ⇒ String

Generates a hexadecimal string with the specified number of characters

Parameters:

  • length (Integer)

    the number of hexadecimal characters to generate (must be >= 0)

Returns:

  • (String)

    a hexadecimal string with lowercase a-f

Raises:

  • (ArgumentError)


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
# File 'lib/pseudo_random.rb', line 42

def hex(length)
  raise ArgumentError, 'Length must be a non-negative integer' unless length.is_a?(Integer) && length >= 0

  return '' if length == 0

  result = ''
  remaining = length

  # Process 8 characters at a time for efficiency (32-bit random number = 8 hex chars)
  while remaining >= 8
    # Generate a 32-bit random number and convert to 8-character hex string
    random_value = @random.rand(2**32)
    hex_chunk = format('%08x', random_value)
    result += hex_chunk
    remaining -= 8
  end

  # Process remaining characters (1-7) by generating 8 chars and taking what we need
  if remaining > 0
    random_value = @random.rand(2**32)
    hex_chunk = format('%08x', random_value)
    result += hex_chunk[0, remaining] # Take only the first 'remaining' characters
  end

  result
end

#rand(max = nil) ⇒ Object

Generates the next pseudo-random number in the sequence If max is provided, returns a value between 0 and max-1 (or 0.0 to max for floats) If a Range is provided, returns a value within that range If no arguments, returns a float between 0.0 and 1.0 (like Ruby’s Kernel.#rand)



31
32
33
34
35
36
37
# File 'lib/pseudo_random.rb', line 31

def rand(max = nil)
  if max.nil?
    @random.rand # Returns float between 0.0 and 1.0
  else
    @random.rand(max)
  end
end