Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# asdf-vm version file
/.tool-versions
44 changes: 43 additions & 1 deletion lib/ex_junk.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ defmodule Junk do
post_op(output, opts)
end

def junk(:long_npi, opts) do
opts = construct_opts(opts)
|> Map.put(:size, 8)
# grab 8 digits, and put a 1 or 2 on the front
junk(Integer, opts)
|> Integer.digits
|> (fn digits -> [8,0,8,4,0] ++ [Enum.random(1..2)] ++ digits end).()
|> Integer.undigits
|> Junk.luhn
end

def junk(:npi, opts) do
junk(:long_npi, opts) - trunc(80840 * :math.pow(10, 10))
end

def junk(f, opts) when is_function(f) do
opts = construct_opts(opts)
apply(f, opts.parameters)
Expand All @@ -49,11 +64,38 @@ defmodule Junk do
end
end

def luhn(number) do
base_digits = Integer.digits(number)
check_sum = base_digits
|> Enum.reverse
|> Junk.map_every(2, fn(n) ->Integer.digits(n*2) end)
|> List.flatten
|> Enum.sum

# calcs the check digit
check_digit = case Kernel.rem(check_sum, 10) do
0 -> 0
n -> 10 - n
end

(base_digits ++ [check_digit]) |> Integer.undigits
end

def map_every(enumerable, nth, mapper) do
{res, _acc} = Enum.map_reduce(enumerable, 0, fn(x, i) -> if (rem(i, nth) == 0) do
{mapper.(x), i+1}
else
{x, i+1}
end
end)
res
end

defp construct_opts(opts) do
Enum.into(opts, Map.from_struct(%Junk{}))
end

defp post_op(output, opts) do
output = if opts.prefix, do: "#{opts.prefix}-#{output}", else: output
if opts.prefix, do: "#{opts.prefix}-#{output}", else: output
end
end
24 changes: 24 additions & 0 deletions test/ex_junk_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ defmodule JunkTest do
assert output != Junk.junk(String, byte_size: 5)
end

test "unnecessary options are ignored" do
string = Junk.junk(String, size: 10)
integer = Junk.junk(Integer, byte_size: "asdf")
assert is_binary(string) == true
assert integer |> is_integer == true
end

test "returns unique Strings" do
output = Junk.junk(String)
assert is_binary(output) == true
Expand Down Expand Up @@ -79,6 +86,23 @@ defmodule JunkTest do
assert "123-45-6789" = output
end

test ":npi returns a short NPI" do
digits = Junk.junk(:npi) |> Integer.digits
assert Kernel.length(digits) == 10
assert Enum.member?([1,2], List.first(digits))
end

test ":long_npi returns a long NPI" do
digits = Junk.junk(:long_npi) |> Integer.digits
assert Kernel.length(digits) == 15
first_6 = digits |> Enum.take(6) |> Integer.undigits
assert Enum.member?([808401,808402], first_6)
end

test "luhn returns a luhn'd number" do
assert Junk.luhn(80840268496713) == 808402684967138
end

def ssn do
"123-45-6789"
end
Expand Down