Verhoeff Check Digit Algorithm in Erlang

If you are going to implement a Check Digit algorythm for a nwe Product, don’t stay with some inferior thing like the EAN Check Digit. Seemingly the Verhoeff algorithm is by far superior in catching common data entry errors happening to humans.

Let’s calculate the Check Digit for a String in Erlang:

-define(DIHEDRAL_A, {{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
                     { 1, 2, 3, 4, 0, 6, 7, 8, 9, 5 },
                     { 2, 3, 4, 0, 1, 7, 8, 9, 5, 6 },
                     { 3, 4, 0, 1, 2, 8, 9, 5, 6, 7 },
                     { 4, 0, 1, 2, 3, 9, 5, 6, 7, 8 },
                     { 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 },
                     { 6, 5, 9, 8, 7, 1, 0, 4, 3, 2 },
                     { 7, 6, 5, 9, 8, 2, 1, 0, 4, 3 },
                     { 8, 7, 6, 5, 9, 3, 2, 1, 0, 4 },
                     { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }}).
-define(DIHEDRAL_INVERSE, {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}).
-define(DIHEDRAL_P, {{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
                     { 1, 5, 7, 6, 2, 8, 3, 0, 9, 4 },
                     { 5, 8, 0, 3, 7, 9, 6, 1, 4, 2 },
                     { 8, 9, 1, 6, 0, 4, 3, 5, 2, 7 },
                     { 9, 4, 5, 3, 1, 2, 6, 8, 7, 0 },
                     { 4, 2, 8, 6, 5, 7, 3, 9, 0, 1 },
                     { 2, 7, 9, 3, 8, 0, 6, 4, 1, 5 },
                     { 7, 0, 4, 6, 9, 1, 3, 2, 5, 8 }}).

verhoeff_digit_helper(Char, {Pos, X}) ->
    Pval = element((Char-$0)+1,
                    element(((Pos+1) rem 8)+1, ?DIHEDRAL_P)),
    XNew = element(Pval+1, element(X+1, ?DIHEDRAL_A)),
    {Pos + 1, XNew}.

verhoeff_digit(NumStr) ->
    {_, X} = lists:foldl(fun(Char, Acc) ->
                             verhoeff_digit_helper(Char, Acc)
                         end,
                        {0, 0}, lists:reverse(NumStr)),
    [$0 + element(X+1, ?DIHEDRAL_INVERSE)].

[$9] = verhoeff_digit("123456654321").

Unfortunately there are various (contradicting) implementation guidelines for the Verhoeff algorithm. I followed Perl’s Algorithm::Verhoeff, Jonathan Mohr and Wikipedia.

Leave a Reply