Current section
Files
Jump to
Current section
Files
lib/luhn.ex
defmodule Luhn do
require Integer
@spec valid?(integer, 2..36, 2..36 | nil) :: boolean
def valid?(number, base \\ 10, mod \\ nil) do
checksum(number, base, mod)
|> Kernel.==(0)
end
def checksum(number, base \\ 10, mod \\ nil)
@spec checksum(integer, 2..36, 2..36 | nil) :: integer
def checksum(number, base, mod) when is_integer(number) do
number
|> Integer.to_string(base)
|> checksum(base, mod)
end
@spec checksum(String.t, 2..36, 2..36 | nil) :: integer
def checksum(number, base, mod) do
mod = mod || base
number
|> String.split("", trim: true)
|> Enum.reduce([], fn(n, acc) -> [String.to_integer(n, base)|acc] end)
|> double(mod)
|> rem(mod)
end
defp double([], _), do: 0
defp double([x], _), do: x
defp double([x,y|tail], mod), do: x + sum(y * 2, mod) + double(tail, mod)
defp sum(number, mod) when number >= mod, do: sum(number - mod + 1, mod)
defp sum(number, _), do: number
end