Current section
Files
Jump to
Current section
Files
lib/random.ex
defmodule Misc.Random do
def seed_random do
try do
get_otp_version() |> seed()
catch
_, _ -> seed()
end
end
def get_otp_version do
:otp_release
|> :erlang.system_info()
|> to_string()
|> Integer.parse()
|> elem(0)
end
# this work on OTP 17 w/o warnings
def seed do
:erlang.now() |> :random.seed()
end
def seed(otp_version) when otp_version <= 17 do
seed()
end
# use of erlang.now is deprecated in OTP 18
def seed(otp_version) when otp_version == 18 do
:erlang.monotonic_time() |> :random.seed()
end
# random is deperecated for rand in OTP 19
def seed(otp_version) when otp_version >= 19 do
now = {
:erlang.phash2([node()]),
:erlang.monotonic_time(),
:erlang.unique_integer()
}
:rand.seed(:exsplus, now)
end
@doc """
Generates a random string that will always start with a character.
"""
def string(length \\ 8) do
seed_random()
get_string(length)
end
defp get_string(1) do
default_alphabet(:alpha) |> get_random_char
end
defp get_string(length) when length > 1 do
first = get_string(1)
rest = Enum.map_join(2..length, fn _ -> default_alphabet() |> get_random_char() end)
first <> rest
end
def get_random_char(alphabet) do
alphabet_length = alphabet |> String.length
get_random_char(alphabet, alphabet_length)
end
def get_random_char(alphabet, alphabet_length) do
alphabet |> String.at(uniform(alphabet_length) - 1)
end
@doc """
Generates a random number as string that will not start with leading zeroes.
"""
def number(length \\ 8) do
seed_random()
length
|> get_number()
|> Integer.parse()
|> elem(0)
end
defp get_number(1) do
default_alphabet(:numeric_wo_zeroes) |> get_random_char()
end
defp get_number(length) when is_integer(length) do
first = get_number(1)
rest = Enum.map_join(2..length, fn _ -> default_alphabet(:numeric) |> get_random_char end)
first <> rest
end
def default_alphabet do
default_alphabet(:alpha) <> default_alphabet(:numeric)
end
def default_alphabet(:alpha) do
"abcdefghijklmnopqrstuvwxyz" <> "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
end
def default_alphabet(:numeric) do
default_alphabet(:numeric_wo_zeroes) <> "0"
end
def default_alphabet(:numeric_wo_zeroes) do
"123456789"
end
def uniform(x) do
try do
get_otp_version() |> get_uniform(x)
catch
_, _ -> get_uniform(x)
end
end
def get_uniform(x), do: x |> :random.uniform
def get_uniform(otp_version, x) when otp_version <= 18, do: x |> get_uniform(x)
def get_uniform(otp_version, x) when is_integer(otp_version), do: x |> :rand.uniform
end