Simplification of ahmadshah/randomizer.ex with seeded RNG.
defmodule Randomizer do
# Generate the various lists at compile time for better performance and scalability
@upcase Enum.to_list(?A..?Z)
@downcase Enum.to_list(?a..?z)
@alpha @upcase ++ @downcase
@numeric Enum.to_list(?0..?9)
@all @alpha ++ @numeric
defp list(:upcase), do: @upcase
defp list(:downcase), do: @downcase
defp list(:alpha), do: @alpha
defp list(:numeric), do: @numeric
defp list(_), do: @all
def randomize(length, seed, type \\ :all) do
:rand.seed(:exsss, [seed])
list = list(type)
# When length == 1, Enum.to_list(1..1) == [1]
1..length
|> Enum.map(fn _ -> Enum.random(list) end)
|> List.to_string()
end
end
ExUnit.start()
defmodule RandomizerTest do
use ExUnit.Case
test "generate random string" do
random = Randomizer.randomize(10, 123)
assert 10 = String.length(random)
assert String.match?(random, ~r/[A-Za-z0-9]/)
end
test "generate random numbers" do
random = Randomizer.randomize(10, 123, :numeric)
assert 10 = String.length(random)
refute String.match?(random, ~r/[A-Za-z]/)
end
test "generate random upper case" do
random = Randomizer.randomize(10, 123, :upcase)
assert 10 = String.length(random)
refute String.match?(random, ~r/[a-z0-9]/)
end
test "generate random lower case" do
random = Randomizer.randomize(10, 123, :downcase)
assert 10 = String.length(random)
refute String.match?(random, ~r/[A-Z0-9]/)
end
test "generate random alphabets only" do
random = Randomizer.randomize(10, 123, :alpha)
assert 10 = String.length(random)
refute String.match?(random, ~r/[0-9]/)
end
test "generate same output with same seed" do
r1 = Randomizer.randomize(10, 123)
r2 = Randomizer.randomize(10, 123)
assert r1 == r2
end
test "generate different output with different seed" do
r1 = Randomizer.randomize(10, 123)
r2 = Randomizer.randomize(10, 124)
refute r1 == r2
end
end
ExUnit.run()