Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Show comment
Hide comment
@rainysia

rainysia Aug 27, 2012

9) { $val -=9; } $sum += $val; } return(($sum % 10) == 0); } if (! is_valid_nums($_POST['nums'])) { echo 'the num is invalid.'; } } ?>

rainysia commented Aug 27, 2012

9) { $val -=9; } $sum += $val; } return(($sum % 10) == 0); } if (! is_valid_nums($_POST['nums'])) { echo 'the num is invalid.'; } } ?>
@spiro79

This comment has been minimized.

Show comment
Hide comment
@spiro79

spiro79 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

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

This comment has been minimized.

Show comment
Hide comment
@gajus

gajus 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;
}

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

This comment has been minimized.

Show comment
Hide comment
@dochenaj

dochenaj Jul 11, 2013

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.

dochenaj commented Jul 11, 2013

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 comment has been minimized.

Show comment
Hide comment
@liamzdenek

liamzdenek Jun 20, 2014

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);

liamzdenek commented Jun 20, 2014

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

This comment has been minimized.

Show comment
Hide comment
@mikemirten

mikemirten Jun 29, 2015

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;
};

mikemirten commented Jun 29, 2015

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

This comment has been minimized.

Show comment
Hide comment
@locoduffs

locoduffs Jul 17, 2015

= 0; $i--) { $sum += $sumTable[$flip++ & 0x1][$number[$i]]; } return $sum % 10 === 0; }

locoduffs commented Jul 17, 2015

= 0; $i--) { $sum += $sumTable[$flip++ & 0x1][$number[$i]]; } return $sum % 10 === 0; }
@ugokoli

This comment has been minimized.

Show comment
Hide comment
@ugokoli

ugokoli May 29, 2017

        //Using Luhn's algorithm to validate a credit card

        public static function isValidCardNumber($number){
        	settype($number, 'string');
        	$number = preg_replace("/[^0-9]/", "", $number);
        	$numberChecksum= '';
		$reversedNumberArray = str_split(strrev($number));
		foreach ($reversedNumberArray as $i => $d) {
		    $numberChecksum.= (($i % 2) !== 0) ? (string)((int)$d * 2) : $d;
		}
		$sum = array_sum(str_split($numberChecksum));
                return ($sum % 10) === 0;
        }

ugokoli commented May 29, 2017

        //Using Luhn's algorithm to validate a credit card

        public static function isValidCardNumber($number){
        	settype($number, 'string');
        	$number = preg_replace("/[^0-9]/", "", $number);
        	$numberChecksum= '';
		$reversedNumberArray = str_split(strrev($number));
		foreach ($reversedNumberArray as $i => $d) {
		    $numberChecksum.= (($i % 2) !== 0) ? (string)((int)$d * 2) : $d;
		}
		$sum = array_sum(str_split($numberChecksum));
                return ($sum % 10) === 0;
        }
@thomsonimjd

This comment has been minimized.

Show comment
Hide comment
@thomsonimjd

thomsonimjd Jul 20, 2017

is there any possibility to get bpay biller address and info by biller code?

thomsonimjd commented Jul 20, 2017

is there any possibility to get bpay biller address and info by biller code?

@tflori

This comment has been minimized.

Show comment
Hide comment
@tflori

tflori Mar 22, 2018

@mikemirten first I thought thats really small and simple to understand but unfortunately it's wrong. have you tried this with a credit card number of odd length? visas can have 13 - 16 numbers and that fails.

my solution is now:

function validateLuhn(string $number): bool
{
    $sum = '';
    $revNumber = strrev($number);
    $len = strlen($number);

    for ($i = 0; $i < $len; $i++) {
        $sum .= $i & 1 ? $revNumber[$i] * 2 : $revNumber[$i];
    }

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

tflori commented Mar 22, 2018

@mikemirten first I thought thats really small and simple to understand but unfortunately it's wrong. have you tried this with a credit card number of odd length? visas can have 13 - 16 numbers and that fails.

my solution is now:

function validateLuhn(string $number): bool
{
    $sum = '';
    $revNumber = strrev($number);
    $len = strlen($number);

    for ($i = 0; $i < $len; $i++) {
        $sum .= $i & 1 ? $revNumber[$i] * 2 : $revNumber[$i];
    }

    return array_sum(str_split($sum)) % 10 === 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment