Algorithm Implementation/Checksums/Verhoeff Algorithm

From Wikibooks, open books for an open world
Jump to: navigation, search

Contents


[edit] C#

    /// <summary>
    /// For more information cf. http://en.wikipedia.org/wiki/Verhoeff_algorithm/ 
    /// Dihedral Group stuff: http://en.wikipedia.org/wiki/Dihedral_group
    /// Dihedral Group order 10: http://mathworld.wolfram.com/DihedralGroupD5.html
    /// </summary>
    public static class Verhoeff
    {        
 
        // The multiplication table
        static int[,] d  = new int[,]
        {
            {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}
        };
 
        // The permutation table
        static int[,] p = new int[,]
        {
            {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}
        };
 
        // The inverse table
        static int[] inv = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9};
 
 
        /// <summary>
        /// Validates that an entered number is Verhoeff compliant.
        /// NB: Make sure the check digit is the last one!
        /// </summary>
        /// <param name="num"></param>
        /// <returns>True if Verhoeff compliant, otherwise false</returns>
        public static bool validateVerhoeff(string num)
        {
            int c = 0;
            int[] myArray = StringToReversedIntArray(num);
 
            for (int i = 0; i < myArray.Length; i++)
            {
                c = d[c, p[(i % 8), myArray[i]]];
            }
 
            return c == 0;
 
        }
 
        /// <summary>
        /// For a given number generates a Verhoeff digit
        /// Append this check digit to num
        /// </summary>
        /// <param name="num"></param>
        /// <returns>Verhoeff check digit as string</returns>
        public static string generateVerhoeff(string num)
        {
            int c = 0;
            int[] myArray = StringToReversedIntArray(num);
 
            for (int i = 0; i < myArray.Length; i++)
            {
                c = d[c, p[((i + 1) % 8), myArray[i]]];
            }
 
            return inv[c].ToString();
        }
 
 
        /// <summary>
        /// Converts a string to a reversed integer array.
        /// </summary>
        /// <param name="num"></param>
        /// <returns>Reversed integer array</returns>
        private static int[] StringToReversedIntArray(string num)
        {
            int[] myArray = new int[num.Length];    
 
            for(int i = 0; i < num.Length; i++)
            {
                myArray[i] = int.Parse(num.Substring(i, 1));
            }
 
            Array.Reverse(myArray);
 
            return myArray;
 
        }
    }

[edit] VB.NET

''' <summary>
''' For more information cf. http://en.wikipedia.org/wiki/Verhoeff_algorithm
''' Dihedral Group: http://mathworld.wolfram.com/DihedralGroup.html
''' </summary>
''' <remarks></remarks>
Public Class Verhoeff
 
 
    'The multiplication table
    Shared ReadOnly d(,) As Integer = _
    {{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}}
 
    'The permutation table
    Shared ReadOnly p(,) As Integer = _
    {{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}}
 
    'The inverse table
    Shared ReadOnly inv() As Integer = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}
 
 
 
    ''' <summary>
    ''' Validates that an entered number is Verhoeff compliant.
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns>True if Verhoeff compliant, otherwise false</returns>
    ''' <remarks>Make sure the check digit is the last one!</remarks>
    Public Shared Function validateVerhoeff(ByVal num As String) As Boolean
 
        Dim c As Integer = 0
        Dim myArray() As Integer = StringToReversedIntArray(num)
 
        For i As Integer = 0 To myArray.Length - 1
            c = d(c, p((i Mod 8), myArray(i)))
        Next i
 
        Return c.Equals(0)
 
    End Function
 
 
    ''' <summary>
    ''' For a given number generates a Verhoeff digit
    ''' </summary>
    ''' <param name="num"></param>
    ''' <returns>Verhoeff check digit as string</returns>
    ''' <remarks>Append this check digit to num</remarks>
    Public Shared Function generateVerhoeff(ByVal num As String) As String
 
        Dim c As Integer = 0
        Dim myArray() As Integer = StringToReversedIntArray(num)
 
        For i As Integer = 0 To myArray.Length - 1
            c = d(c, p(((i + 1) Mod 8), myArray(i)))
        Next i
 
        Return inv(c).ToString
 
    End Function
 
 
    ''' <summary>
    ''' Converts a string to a reversed integer array.
    ''' </summary>
    ''' <param name="str"></param>
    ''' <returns>Reversed integer array</returns>
    ''' <remarks></remarks>
    Private Shared Function StringToReversedIntArray(ByVal str As String) As Integer()
 
        Dim myArray(str.Length - 1) As Integer
 
        For i As Integer = 0 To str.Length - 1
            myArray(i) = Convert.ToInt16(str.Substring(i, 1))
            'we could use myArray(i) = Convert.ToInt16(str(i)) - 48 '48 is from Convert.ToInt16("0"c)
        Next
 
        Array.Reverse(myArray)
 
        Return myArray
 
        'A more modern version of this may look something like this
        'Return (From I In str.ToArray
        '        Select CInt(I.ToString)).Reverse.ToArray
 
    End Function
 
End Class

[edit] VB for Applications

''' <summary>
''' For more information cf. http://en.wikipedia.org/wiki/Verhoeff_algorithm
''' Dihedral Group: http://mathworld.wolfram.com/DihedralGroup.html
''' You can use this code in Excel, Access, etc...
''' </summary>
''' <remarks></remarks>
 
'The multiplication table
Dim d(0 To 9) As Variant
'The permutation table
Dim p(0 To 8) As Variant
'The inverse table
Dim inv(0 To 9) As Integer
 
Private Sub initVerhoeffConsts()
    If IsArray(d(0)) Then Exit Sub 'Shortcut if already initiated
    d(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    d(1) = Array(1, 2, 3, 4, 0, 6, 7, 8, 9, 5)
    d(2) = Array(2, 3, 4, 0, 1, 7, 8, 9, 5, 6)
    d(3) = Array(3, 4, 0, 1, 2, 8, 9, 5, 6, 7)
    d(4) = Array(4, 0, 1, 2, 3, 9, 5, 6, 7, 8)
    d(5) = Array(5, 9, 8, 7, 6, 0, 4, 3, 2, 1)
    d(6) = Array(6, 5, 9, 8, 7, 1, 0, 4, 3, 2)
    d(7) = Array(7, 6, 5, 9, 8, 2, 1, 0, 4, 3)
    d(8) = Array(8, 7, 6, 5, 9, 3, 2, 1, 0, 4)
    d(9) = Array(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
 
    p(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    p(1) = Array(1, 5, 7, 6, 2, 8, 3, 0, 9, 4)
    p(2) = Array(5, 8, 0, 3, 7, 9, 6, 1, 4, 2)
    p(3) = Array(8, 9, 1, 6, 0, 4, 3, 5, 2, 7)
    p(4) = Array(9, 4, 5, 3, 1, 2, 6, 8, 7, 0)
    p(5) = Array(4, 2, 8, 6, 5, 7, 3, 9, 0, 1)
    p(6) = Array(2, 7, 9, 3, 8, 0, 6, 4, 1, 5)
    p(7) = Array(7, 0, 4, 6, 9, 1, 3, 2, 5, 8)
 
    inv(0) = 0: inv(1) = 4: inv(2) = 3: inv(3) = 2: inv(4) = 1
    inv(5) = 5: inv(6) = 6: inv(7) = 7: inv(8) = 8: inv(9) = 9
End Sub
 
 
''' <summary>
''' Validates that an entered number is Verhoeff compliant.
''' </summary>
''' <param name="num"></param>
''' <returns>True if Verhoeff compliant, otherwise false</returns>
''' <remarks>Make sure the check digit is the last one!</remarks>
Public Function validateVerhoeff(ByVal num As String) As Boolean
        initVerhoeffConsts
        Dim c As Integer
        Dim i As Integer
        c = 0
        Dim myArray() As Integer
        myArray = StringToReversedIntArray(num)
 
        For i = 0 To UBound(myArray)
            c = d(c)(p((i Mod 8))(myArray(i)))
        Next i
 
        validateVerhoeff = (c = 0)
End Function
 
 
''' <summary>
''' For a given number generates a Verhoeff digit
''' </summary>
''' <param name="num"></param>
''' <returns>Verhoeff check digit as Integer</returns>
''' <remarks>Append this check digit to num</remarks>
Public Function generateVerhoeff(ByVal num As String) As Integer
    initVerhoeffConsts
    Dim c As Integer
    Dim i As Integer    
    c = 0
    Dim myArray() As Integer
    myArray = StringToReversedIntArray(num)
 
    For i = 0 To UBound(myArray)
        c = d(c)(p((i + 1) Mod 8)(myArray(i)))
    Next i
 
    generateVerhoeff = inv(c) 'str(inv(c))
End Function
 
 
''' <summary>
''' Converts a string to a reversed integer array.
''' </summary>
''' <param name="str"></param>
''' <returns>Reversed integer array</returns>
''' <remarks></remarks>
Private Function StringToReversedIntArray(ByVal str As String) As Integer()
    Dim lg As Integer
    lg = Len(str)
    Dim myArray() As Integer
    ReDim myArray(0 To lg - 1)
    Dim i As Integer
 
    For i = 0 To lg - 1
        myArray(i) = AscW(Mid$(str, lg - i, 1)) - AscW("0")
    Next
    StringToReversedIntArray = myArray
End Function
 
Public Sub _AssertsVerhoeff()
    Debug.Print "Start Verhoeff's Asserts"
    Debug.Assert generateVerhoeff("75872") = 2
    Debug.Assert validateVerhoeff("758722") = True
    Debug.Assert generateVerhoeff("12345") = 1
    Debug.Assert validateVerhoeff("123451") = True
    Debug.Assert generateVerhoeff("142857") = 0
    Debug.Assert validateVerhoeff("1428570") = True
    Debug.Assert generateVerhoeff("123456789012") = 0
    Debug.Assert validateVerhoeff("1234567890120") = True
    Debug.Assert generateVerhoeff("8473643095483728456789") = 2
    Debug.Assert validateVerhoeff("84736430954837284567892") = True
    Debug.Assert generateVerhoeff("12345") = 1
    Debug.Assert validateVerhoeff("123451") = True
    Debug.Assert validateVerhoeff("124351") = False
    Debug.Assert validateVerhoeff("122451") = False
    Debug.Assert validateVerhoeff("128451") = False
    Debug.Assert validateVerhoeff("214315") = False
    Debug.Print "End Verhoeff's Asserts"
End Sub

[edit] Java

/**
 * @see <a href="http://en.wikipedia.org/wiki/Verhoeff_algorithm/">More Info</a>
 * @see <a href="http://en.wikipedia.org/wiki/Dihedral_group">Dihedral Group</a>
 * @see <a href="http://mathworld.wolfram.com/DihedralGroupD5.html">Dihedral Group Order 10</a>
 * @author Colm Rice
 */
public class Verhoeff {
 
 
    // The multiplication table
    static int[][] d  = new int[][]
    {
        {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}
    };
 
    // The permutation table
    static int[][] p = new int[][]
    {
        {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}
    };
 
    // The inverse table
    static int[] inv = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9};
 
 
    /* 
     * For a given number generates a Verhoeff digit
     * 
     */
        public static String generateVerhoeff(String num){
 
                int c = 0;
                int[] myArray = StringToReversedIntArray(num);
 
                for(int i = 0; i < myArray.length; i++)
                {
                        c = d[c][p[((i + 1) % 8)] [myArray[i]]];
                }
 
                return Integer.toString(inv[c]);
        }
 
 
        /*
         * Validates that an entered number is Verhoeff compliant.
         * NB: Make sure the check digit is the last one.
         */
        public static boolean validateVerhoeff(String num){
 
                int c = 0;
                int[] myArray = StringToReversedIntArray(num);
 
                for (int i = 0; i < myArray.length; i++)
                {
                        c = d[c][p[(i % 8)][myArray[i]]];
                }
 
                return (c == 0);
        }
 
 
 
        /*
         * Converts a string to a reversed integer array.
         */
        private static int[] StringToReversedIntArray(String num){
 
                int[] myArray = new int[num.length()];
 
                for(int i = 0; i < num.length(); i++)
                {
                        myArray[i] = Integer.parseInt(num.substring(i, i + 1));                                    
                }
 
                myArray = Reverse(myArray);
 
                return myArray;
 
        }
 
        /*
         * Reverses an int array
         */
        private static int[] Reverse(int[] myArray)
        {
                int[] reversed = new int[myArray.length];
 
                for(int i = 0; i < myArray.length ; i++)
                {
                        reversed[i] = myArray[myArray.length - (i + 1)];                    
                }
 
                return reversed;
        }
 
 
}

[edit] Python

# @see <a href="http://en.wikipedia.org/wiki/Verhoeff_algorithm/">More Info</a>
# @see <a href="http://en.wikipedia.org/wiki/Dihedral_group">Dihedral Group</a>
# @see <a href="http://mathworld.wolfram.com/DihedralGroupD5.html">Dihedral Group Order 10</a>
# @author Hermann Himmelbauer
 
verhoeff_table_d = (
    (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))
verhoeff_table_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_table_inv = (0,4,3,2,1,5,6,7,8,9)
 
def calcsum(number):
    """For a given number returns a Verhoeff checksum digit"""
    c = 0
    for i, item in enumerate(reversed(str(number))):
        c = verhoeff_table_d[c][verhoeff_table_p[(i+1)%8][int(item)]]
    return verhoeff_table_inv[c]
 
def checksum(number):
    """For a given number generates a Verhoeff digit and
    returns number + digit"""
    c = 0
    for i, item in enumerate(reversed(str(number))):
        c = verhoeff_table_d[c][verhoeff_table_p[i % 8][int(item)]]
    return c
 
def generateVerhoeff(number):
    """For a given number returns number + Verhoeff checksum digit"""
    return "%s%s" % (number, calcsum(number))
 
def validateVerhoeff(number):
    """Validate Verhoeff checksummed number (checksum is last digit)"""
    return checksum(number) == 0
 
# Some tests and also usage examples
assert calcsum('75872') == 2
assert checksum('758722') == 0
assert calcsum('12345') == 1
assert checksum('123451') == 0
assert calcsum('142857') == 0
assert checksum('1428570') == 0
assert calcsum('123456789012') == 0
assert checksum('1234567890120') == 0
assert calcsum('8473643095483728456789') == 2
assert checksum('84736430954837284567892') == 0
assert generateVerhoeff('12345') == '123451'
assert validateVerhoeff('123451') == True
assert validateVerhoeff('122451') == False
assert validateVerhoeff('128451') == False

[edit] D

import std.conv;
 
// tested with D version 2
void main(){
    assert(validateVerhoeff("123451") == true);
    assert(validateVerhoeff("122451") == false);
    assert(validateVerhoeff("128451") == false);
}
 
// The multiplication table
immutable ubyte[10][10] d = [
    [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]
];
 
// The permutation table
immutable ubyte[10][8] 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]
];
 
// The inverse table
immutable ubyte[10] inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9];
 
public string generateVerhoeff(string s){
    int c;
    int[] a = reversedStringToIntArray(s);
    for(int i = 0; i < a.length; i++) {
        c = d[c][p[((i + 1) % 8)] [a[i]]];
    }
    return to!string(inv[c]);
}
 
public bool validateVerhoeff(string s) {
    int c;
    int[] a = reversedStringToIntArray(s);
    for (int i = 0; i < a.length; i++) {
        c = d[c][p[(i % 8)][a[i]]];
    }
    return (c == 0);
}
 
private int[] reversedStringToIntArray(string s){
    int[] a = new int[](s.length);
    for (int i, ri = s.length - 1; i < s.length; i++, ri--) {
        a[i] = s[ri] - '0';
    }
    return a;
}

[edit] PHP

<?php
# @author Semyon Velichko

class Verhoeff {
 
    static public $d = array(
        array(0,1,2,3,4,5,6,7,8,9),
        array(1,2,3,4,0,6,7,8,9,5),
        array(2,3,4,0,1,7,8,9,5,6),
        array(3,4,0,1,2,8,9,5,6,7),
        array(4,0,1,2,3,9,5,6,7,8),
        array(5,9,8,7,6,0,4,3,2,1),
        array(6,5,9,8,7,1,0,4,3,2),
        array(7,6,5,9,8,2,1,0,4,3),
        array(8,7,6,5,9,3,2,1,0,4),
        array(9,8,7,6,5,4,3,2,1,0)
    );
 
    static public $p = array(
        array(0,1,2,3,4,5,6,7,8,9),
        array(1,5,7,6,2,8,3,0,9,4),
        array(5,8,0,3,7,9,6,1,4,2),
        array(8,9,1,6,0,4,3,5,2,7),
        array(9,4,5,3,1,2,6,8,7,0),
        array(4,2,8,6,5,7,3,9,0,1),
        array(2,7,9,3,8,0,6,4,1,5),
        array(7,0,4,6,9,1,3,2,5,8)
    );
 
    static public $inv = array(0,4,3,2,1,5,6,7,8,9);
 
    static function calc($num) {
        if(!preg_match('/^[0-9]+$/', $num)) {
            throw new \InvalidArgumentException(sprintf("Error! Value is restricted to the number, %s is not a number.",
                                                    $num));
        }
 
        $r = 0;
        foreach(array_reverse(str_split($num)) as $n => $N) {
            $r = self::$d[$r][self::$p[($n+1)%8][$N]];
        }
        return self::$inv[$r];
    }
 
    static function check($num) {
        if(!preg_match('/^[0-9]+$/', $num)) {
            throw new \InvalidArgumentException(sprintf("Error! Value is restricted to the number, %s is not a number.",
                                                    $num));
        }
 
        $r = 0;
        foreach(array_reverse(str_split($num)) as $n => $N) {
            $r = self::$d[$r][self::$p[$n%8][$N]];
        }
        return $r;
    }
 
    static function generate($num) {
        return sprintf("%s%s", $num, self::calc($num));
    }
 
    static function validate($num) {
        return self::check($num) === 0;
    }
 
}
 
# Some tests and also usage examples
assert("Verhoeff::calc('75872') === 2");
assert("Verhoeff::check('758722') === 0");
assert("Verhoeff::calc('12345') === 1");
assert("Verhoeff::check('123451') === 0");
assert("Verhoeff::calc('142857') === 0");
assert("Verhoeff::check('1428570') === 0");
assert("Verhoeff::calc('123456789012') === 0");
assert("Verhoeff::check('1234567890120') === 0");
assert("Verhoeff::calc('8473643095483728456789') === 2");
assert("Verhoeff::check('84736430954837284567892') === 0");
 
assert("Verhoeff::generate('12345') === '123451'");
assert("Verhoeff::validate('123451') === true");
assert("Verhoeff::validate('122451') === false");
assert("Verhoeff::validate('128451') === false");
Personal tools
Namespaces
Variants
Actions
Navigation
Community
Toolbox
Sister projects
Print/export