# <!-- rdoc-file=random.c -->
# Random provides an interface to Ruby's pseudo-random number generator, or
# PRNG.  The PRNG produces a deterministic sequence of bits which approximate
# true randomness. The sequence may be represented by integers, floats, or
# binary strings.
#
# The generator may be initialized with either a system-generated or
# user-supplied seed value by using Random.srand.
#
# The class method Random.rand provides the base functionality of Kernel.rand
# along with better handling of floating point values. These are both interfaces
# to the Ruby system PRNG.
#
# Random.new will create a new PRNG with a state independent of the Ruby system
# PRNG, allowing multiple generators with different seed values or sequence
# positions to exist simultaneously. Random objects can be marshaled, allowing
# sequences to be saved and resumed.
#
# PRNGs are currently implemented as a modified Mersenne Twister with a period
# of 2**19937-1.  As this algorithm is *not* for cryptographical use, you must
# use SecureRandom for security purpose, instead of this PRNG.
#
class Random < Object
  include Random::Formatter

  # <!--
  #   rdoc-file=random.c
  #   - prng1 == prng2 -> true or false
  # -->
  # Returns true if the two generators have the same internal state, otherwise
  # false.  Equivalent generators will return the same sequence of pseudo-random
  # numbers.  Two generators will generally have the same state only if they were
  # initialized with the same seed
  #
  #     Random.new == Random.new             # => false
  #     Random.new(1234) == Random.new(1234) # => true
  #
  # and have the same invocation history.
  #
  #     prng1 = Random.new(1234)
  #     prng2 = Random.new(1234)
  #     prng1 == prng2 # => true
  #
  #     prng1.rand     # => 0.1915194503788923
  #     prng1 == prng2 # => false
  #
  #     prng2.rand     # => 0.1915194503788923
  #     prng1 == prng2 # => true
  #
  def ==: (untyped arg0) -> bool

  # <!--
  #   rdoc-file=random.c
  #   - prng.bytes(size) -> string
  # -->
  # Returns a random binary string containing `size` bytes.
  #
  #     random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
  #     random_string.size                   # => 10
  #
  def bytes: (Integer size) -> String

  # <!--
  #   rdoc-file=random.c
  #   - Random.new(seed = Random.new_seed) -> prng
  # -->
  # Creates a new PRNG using `seed` to set the initial state. If `seed` is
  # omitted, the generator is initialized with Random.new_seed.
  #
  # See Random.srand for more information on the use of seed values.
  #
  def initialize: (?Integer seed) -> void

  # <!--
  #   rdoc-file=random.c
  #   - prng.rand -> float
  #   - prng.rand(max) -> number
  #   - prng.rand(range) -> number
  # -->
  # When `max` is an Integer, `rand` returns a random integer greater than or
  # equal to zero and less than `max`. Unlike Kernel.rand, when `max` is a
  # negative integer or zero, `rand` raises an ArgumentError.
  #
  #     prng = Random.new
  #     prng.rand(100)       # => 42
  #
  # When `max` is a Float, `rand` returns a random floating point number between
  # 0.0 and `max`, including 0.0 and excluding `max`.
  #
  #     prng.rand(1.5)       # => 1.4600282860034115
  #
  # When `range` is a Range, `rand` returns a random number where
  # `range.member?(number) == true`.
  #
  #     prng.rand(5..9)      # => one of [5, 6, 7, 8, 9]
  #     prng.rand(5...9)     # => one of [5, 6, 7, 8]
  #     prng.rand(5.0..9.0)  # => between 5.0 and 9.0, including 9.0
  #     prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
  #
  # Both the beginning and ending values of the range must respond to subtract
  # (`-`) and add (`+`)methods, or rand will raise an ArgumentError.
  #
  def rand: () -> Float
          | (Integer | ::Range[Integer] max) -> Integer
          | (Float | ::Range[Float] max) -> Float

  # <!--
  #   rdoc-file=random.c
  #   - prng.seed -> integer
  # -->
  # Returns the seed value used to initialize the generator. This may be used to
  # initialize another generator with the same state at a later time, causing it
  # to produce the same sequence of numbers.
  #
  #     prng1 = Random.new(1234)
  #     prng1.seed       #=> 1234
  #     prng1.rand(100)  #=> 47
  #
  #     prng2 = Random.new(prng1.seed)
  #     prng2.rand(100)  #=> 47
  #
  def seed: () -> Integer

  # <!--
  #   rdoc-file=random.c
  #   - Random.new_seed -> integer
  # -->
  # Returns an arbitrary seed value. This is used by Random.new when no seed value
  # is specified as an argument.
  #
  #     Random.new_seed  #=> 115032730400174366788466674494640623225
  #
  def self.new_seed: () -> Integer

  # <!--
  #   rdoc-file=random.c
  #   - Random.rand -> float
  #   - Random.rand(max) -> number
  #   - Random.rand(range) -> number
  # -->
  # Returns a random number using the Ruby system PRNG.
  #
  # See also Random#rand.
  #
  def self.rand: () -> Float
               | (Integer | ::Range[Integer] max) -> Integer
               | (Float | ::Range[Float] max) -> Float

  # <!--
  #   rdoc-file=random.c
  #   - srand(number = Random.new_seed) -> old_seed
  # -->
  # Seeds the system pseudo-random number generator, with `number`. The previous
  # seed value is returned.
  #
  # If `number` is omitted, seeds the generator using a source of entropy provided
  # by the operating system, if available (/dev/urandom on Unix systems or the RSA
  # cryptographic provider on Windows), which is then combined with the time, the
  # process id, and a sequence number.
  #
  # srand may be used to ensure repeatable sequences of pseudo-random numbers
  # between different runs of the program. By setting the seed to a known value,
  # programs can be made deterministic during testing.
  #
  #     srand 1234               # => 268519324636777531569100071560086917274
  #     [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
  #     [ rand(10), rand(1000) ] # => [4, 664]
  #     srand 1234               # => 1234
  #     [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
  #
  def self.srand: (?Integer number) -> Integer
end

Random::DEFAULT: Random

# <!-- rdoc-file=lib/random/formatter.rb -->
# ## Random number formatter.
#
# Formats generated random numbers in many manners.
#
# ### Examples
#
# Generate random hexadecimal strings:
#
#     require 'random/formatter'
#
#     prng.hex(10) #=> "52750b30ffbc7de3b362"
#     prng.hex(10) #=> "92b15d6c8dc4beb5f559"
#     prng.hex(13) #=> "39b290146bea6ce975c37cfc23"
#
# Generate random base64 strings:
#
#     prng.base64(10) #=> "EcmTPZwWRAozdA=="
#     prng.base64(10) #=> "KO1nIU+p9DKxGg=="
#     prng.base64(12) #=> "7kJSM/MzBJI+75j8"
#
# Generate random binary strings:
#
#     prng.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
#     prng.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
#
# Generate alphanumeric strings:
#
#     prng.alphanumeric(10) #=> "S8baxMJnPl"
#     prng.alphanumeric(10) #=> "aOxAg8BAJe"
#
# Generate UUIDs:
#
#     prng.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
#     prng.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
#
# <!-- rdoc-file=random.c -->
# Generate a random number in the given range as Random does
#
#     prng.random_number       #=> 0.5816771641321361
#     prng.random_number(1000) #=> 485
#     prng.random_number(1..6) #=> 3
#     prng.rand                #=> 0.5816771641321361
#     prng.rand(1000)          #=> 485
#     prng.rand(1..6)          #=> 3
#
module Random::Formatter
  # <!--
  #   rdoc-file=lib/random/formatter.rb
  #   - base64(n=nil)
  # -->
  # Random::Formatter#base64 generates a random base64 string.
  #
  # The argument *n* specifies the length, in bytes, of the random number to be
  # generated. The length of the result string is about 4/3 of *n*.
  #
  # If *n* is not specified or is nil, 16 is assumed. It may be larger in the
  # future.
  #
  # The result may contain A-Z, a-z, 0-9, "+", "/" and "=".
  #
  #     require 'random/formatter'
  #
  #     prng.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
  #     prng.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
  #
  # See RFC 3548 for the definition of base64.
  #
  def base64: (?Integer? n) -> String

  # <!--
  #   rdoc-file=lib/random/formatter.rb
  #   - hex(n=nil)
  # -->
  # Random::Formatter#hex generates a random hexadecimal string.
  #
  # The argument *n* specifies the length, in bytes, of the random number to be
  # generated. The length of the resulting hexadecimal string is twice of *n*.
  #
  # If *n* is not specified or is nil, 16 is assumed. It may be larger in the
  # future.
  #
  # The result may contain 0-9 and a-f.
  #
  #     require 'random/formatter'
  #
  #     prng.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
  #     prng.hex #=> "91dc3bfb4de5b11d029d376634589b61"
  #
  def hex: (?Integer? n) -> String

  # <!-- rdoc-file=random.c -->
  # Generates formatted random number from raw random bytes. See Random#rand.
  #
  def rand: () -> Float
          | (?Float? n) -> Float
          | (?Integer? n) -> Integer
          | (?Numeric? n) -> Numeric
          | (?::Range[Float]? n) -> Float
          | (?::Range[Integer]? n) -> Integer
          | (?::Range[Numeric]? n) -> Numeric

  # <!--
  #   rdoc-file=lib/random/formatter.rb
  #   - random_bytes(n=nil)
  # -->
  # Random::Formatter#random_bytes generates a random binary string.
  #
  # The argument *n* specifies the length of the result string.
  #
  # If *n* is not specified or is nil, 16 is assumed. It may be larger in future.
  #
  # The result may contain any byte: "x00" - "xff".
  #
  #     require 'random/formatter'
  #
  #     prng.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
  #     prng.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
  #
  def random_bytes: (?Integer? n) -> String

  # <!--
  #   rdoc-file=random.c
  #   - prng.random_number        -> float
  #   - prng.random_number(max)   -> number
  #   - prng.random_number(range) -> number
  #   - prng.rand                 -> float
  #   - prng.rand(max)            -> number
  #   - prng.rand(range)          -> number
  # -->
  # Generates formatted random number from raw random bytes. See Random#rand.
  #
  def random_number: () -> Float
                   | (?Float? n) -> Float
                   | (?Integer? n) -> Integer
                   | (?Numeric? n) -> Numeric
                   | (?::Range[Float]? n) -> Float
                   | (?::Range[Integer]? n) -> Integer
                   | (?::Range[Numeric]? n) -> Numeric

  # <!--
  #   rdoc-file=lib/random/formatter.rb
  #   - urlsafe_base64(n=nil, padding=false)
  # -->
  # Random::Formatter#urlsafe_base64 generates a random URL-safe base64 string.
  #
  # The argument *n* specifies the length, in bytes, of the random number to be
  # generated. The length of the result string is about 4/3 of *n*.
  #
  # If *n* is not specified or is nil, 16 is assumed. It may be larger in the
  # future.
  #
  # The boolean argument *padding* specifies the padding. If it is false or nil,
  # padding is not generated. Otherwise padding is generated. By default, padding
  # is not generated because "=" may be used as a URL delimiter.
  #
  # The result may contain A-Z, a-z, 0-9, "-" and "_". "=" is also used if
  # *padding* is true.
  #
  #     require 'random/formatter'
  #
  #     prng.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
  #     prng.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
  #
  #     prng.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
  #     prng.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
  #
  # See RFC 3548 for the definition of URL-safe base64.
  #
  def urlsafe_base64: (?Integer? n, ?boolish padding) -> String

  # <!--
  #   rdoc-file=lib/random/formatter.rb
  #   - uuid()
  # -->
  # Random::Formatter#uuid generates a random v4 UUID (Universally Unique
  # IDentifier).
  #
  #     require 'random/formatter'
  #
  #     prng.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
  #     prng.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
  #     prng.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
  #
  # The version 4 UUID is purely random (except the version). It doesn't contain
  # meaningful information such as MAC addresses, timestamps, etc.
  #
  # The result contains 122 random bits (15.25 random bytes).
  #
  # See RFC 4122 for details of UUID.
  #
  def uuid: () -> String
end
