Skip to content

Instantly share code, notes, and snippets.

@ahmadshah
Created September 1, 2016 10:28
Show Gist options
  • Save ahmadshah/8d978bbc550128cca12dd917a09ddfb7 to your computer and use it in GitHub Desktop.
Save ahmadshah/8d978bbc550128cca12dd917a09ddfb7 to your computer and use it in GitHub Desktop.
Random string in elixir
defmodule Randomizer do
@moduledoc """
Random string generator module.
"""
@doc """
Generate random string based on the given legth. It is also possible to generate certain type of randomise string using the options below:
* :all - generate alphanumeric random string
* :alpha - generate nom-numeric random string
* :numeric - generate numeric random string
* :upcase - generate upper case non-numeric random string
* :downcase - generate lower case non-numeric random string
## Example
iex> Iurban.String.randomizer(20) //"Je5QaLj982f0Meb0ZBSK"
"""
def randomizer(length, type \\ :all) do
alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
lists =
cond do
type == :alpha -> alphabets <> String.downcase(alphabets)
type == :numeric -> numbers
type == :upcase -> alphabets
type == :downcase -> String.downcase(alphabets)
true -> alphabets <> String.downcase(alphabets) <> numbers
end
|> String.split("", trim: true)
do_randomizer(length, lists)
end
@doc false
defp get_range(length) when length > 1, do: (1..length)
defp get_range(length), do: [1]
@doc false
defp do_randomizer(length, lists) do
get_range(length)
|> Enum.reduce([], fn(_, acc) -> [Enum.random(lists) | acc] end)
|> Enum.join("")
end
end
defmodule RandomizerTest do
use ExUnit.Case
alias Randomizer
test "generate random string" do
random = Randomizer.randomizer(100)
assert 100 = String.length(random)
assert String.match?(random, ~r/[A-Za-z0-9]/)
end
test "generate random numbers" do
random = Randomizer.randomizer(100, :numeric)
assert 100 = String.length(random)
refute String.match?(random, ~r/[A-Za-z]/)
end
test "generate random upper case" do
random = Randomizer.randomizer(100, :upcase)
assert 100 = String.length(random)
refute String.match?(random, ~r/[a-z0-9]/)
end
test "generate random lower case" do
random = Randomizer.randomizer(100, :downcase)
assert 100 = String.length(random)
refute String.match?(random, ~r/[A-Z0-9]/)
end
test "generate random alphabets only" do
random = Randomizer.randomizer(100, :alpha)
assert 100 = String.length(random)
refute String.match?(random, ~r/[0-9]/)
end
end
@andresmaro
Copy link

Thanks for sharing.

@he9lin
Copy link

he9lin commented Apr 7, 2018

Thanks, this is great!

@talismandev
Copy link

Thanks for sharing!

@otepagustincanilao
Copy link

Thanks a lot for this

@sgobotta
Copy link

Thank you for this. Ever thought making it a hex package?

@shivanikanal
Copy link

shivanikanal commented Jan 21, 2021

Thanks for sharing this!

@ngoclinhng
Copy link

My approach is a much simpler

  @doc """
  A helper functions to generate a random (printable) string of given `len`.

  You could change the hard-coded ascii codes 32 and 126 to only 
  uppercase letters, digits, etc...
  """
  def random_string(len) when is_integer(len) and len > 0 do
    (for _ <- 1..len, do: rand_uniform(32, 126))
    |> List.to_string()
  end

  # Returns a random integer uniformly distributed in the range
  # `n <= X <= m`.
  #
  # If the random variable `X` is uniformly distributed in the range
  # `1 <= X <= m - n + 1`, then r.v `Y = X + n - 1` is uniformly
  # distributed in the range `n <= Y <= m`.
  # (Because we just shift X to the right).
  defp rand_uniform(n, m) do
    :rand.uniform(m - n + 1) # random X
    |> Kernel.+(n - 1)       # shift X to the right to get Y
  end

@warmwaffles
Copy link

If you just want alphanumeric this is fairly handy. It gets the job done for quick random strings in tests.

@characters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

def random_string(len) do
  1..len
  |> Enum.reduce([], fn _, acc -> [Enum.random(@characters) | acc] end)
  |> IO.iodata_to_binary()
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment