Input validation confusion!

Characters are just integers, use it:

def digit_value(d) when d in $0..$9, do: d - $0
def digit_value(d) when d in $a..$z, do: d - $a + 10
def digit_value(d) when d in $A..$Z, do: d - $A + 36

Or you could even metaprogramming roughly like this: (untested)

Enum.concat([$0..$9, $a..$z, $A..$Z])
|> Enum.with_index()
|> Enum.each(fn {d, i} ->
  def digit_value(unquote(d)), do: unquote(i)
end)

There are a lot solutions that are nicer than your module attribute and still benefit from compiletime optimisations.

PS: function calls are (usually) faster than map-lookups.