Create a gist now

Instantly share code, notes, and snippets.

Luhn's algorithm in php
<?php
function is_valid_luhn($number) {
settype($number, 'string');
$sumTable = array(
array(0,1,2,3,4,5,6,7,8,9),
array(0,2,4,6,8,1,3,5,7,9));
$sum = 0;
$flip = 0;
for ($i = strlen($number) - 1; $i >= 0; $i--) {
$sum += $sumTable[$flip++ & 0x1][$number[$i]];
}
return $sum % 10 === 0;
}
@rainysia
9) { $val -=9; } $sum += $val; } return(($sum % 10) == 0); } if (! is_valid_nums($_POST['nums'])) { echo 'the num is invalid.'; } } ?>
@spiro79
spiro79 commented Mar 9, 2013

Please be aware that this functions will only work if the passed argument is a string, else it will fail.
For more info read:

http://lamp-ios.com/?p=256

It has to do with 1 thing:

  1. Your platform (32 or 64 bit)

Be aware of this

@gajus
gajus commented Jul 6, 2013

Here is a simple implementation:

/**
 * @see http://en.wikipedia.org/wiki/Luhn_algorithm
 */
private function checksum ($card_number) {
    $card_number_checksum = '';

    foreach (str_split(strrev((string) $card_number)) as $i => $d) {
        $card_number_checksum .= $i %2 !== 0 ? $d * 2 : $d;
    }

    return array_sum(str_split($card_number_checksum)) % 10 === 0;
}
@dochenaj

You can simply typecast whatever input you have into a string before applying it to the function or you could incorporate a step to first typecast your arguments into strings.

@liamzdenek

This function works perfectly if your number is already in a 16-character string, is_valid_luhn("4111111111111111")

But the function will fail if the string contains any symbols or spaces, is_valid_luhn("4111 1111 1111 1111") = false

This can be easily fixed by placing a preg_replace at the beginning of the function to strip all non-digit characters.

$number = preg_replace("/[^0-9]/", "", $number);
@mikemirten

PHP:

function isValid($num) {
    $num = preg_replace('/[^\d]/', '', $num);
    $sum = '';

    for ($i = strlen($num) - 1; $i >= 0; -- $i) {
        $sum .= $i & 1 ? $num[$i] : $num[$i] * 2;
    }

    return array_sum(str_split($sum)) % 10 === 0;
}

Javascript:

function isValid(number) {
    var num = number.replace(/[^\d]/, '');
    var str = '';

    for (var i = num.length - 1; i >= 0; -- i) {
        str += i & 1 ? num[i] : (parseInt(num[i]) * 2).toString();
    }

    var sum = str.split('').reduce(function(prev, current) {
        return prev + parseInt(current);
    }, 0);

    return sum % 10 === 0;
};
@locoduffs
= 0; $i--) { $sum += $sumTable[$flip++ & 0x1][$number[$i]]; } return $sum % 10 === 0; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment