{{ message }}

Instantly share code, notes, and snippets.

# troelskn/gist:1287893

Created Oct 14, 2011
Luhn's algorithm in php
 = 0; \$i--) { \$sum += \$sumTable[\$flip++ & 0x1][\$number[\$i]]; } return \$sum % 10 === 0; }

### 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 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: Your platform (32 or 64 bit) Be aware of this

### 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 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 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 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 commented Jul 17, 2015

 = 0; \$i--) { \$sum += \$sumTable[\$flip++ & 0x1][\$number[\$i]]; } 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 commented Jul 20, 2017

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

### tflori commented Mar 22, 2018 • edited

 @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 = 0; \$revNumber = strrev(\$number); \$len = strlen(\$number); for (\$i = 0; \$i < \$len; \$i++) { \$sum += \$i & 1 ? (\$revNumber[\$i] > 4 ? \$revNumber[\$i] * 2 - 9 : \$revNumber[\$i] * 2) : \$revNumber[\$i]; } return \$sum % 10 === 0; }``` @mogzol: you are right: the string sum does not make sense... So I removed it. edit fixed the calculation without string split and unused variables

### mogzol commented Sep 12, 2019 • edited

 Alternative version of @tflori's code that doesn't rely on strrev, array_sum or str_split, which makes it more readable IMO, and slightly faster (though at this point it's basically just the original code without the sum table): ```function validateLuhn(string \$number): bool { \$sum = 0; \$flag = 0; for (\$i = strlen(\$number) - 1; \$i >= 0; \$i--) { \$add = \$flag++ & 1 ? \$number[\$i] * 2 : \$number[\$i]; \$sum += \$add > 9 ? \$add - 9 : \$add; } return \$sum % 10 === 0; }```

### mogzol commented Sep 13, 2019 • edited

 @tflori Your updated code doesn't work just FYI. You actually did need the array_sum. This is because of the first step outlined here: https://en.wikipedia.org/wiki/Luhn_algorithm#Description If the result of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), then add the digits of the result (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9) Your original code achieved this by using a string and summing all the numbers in the string. My code uses the alternate method mentioned: alternatively, the same final result can be found by subtracting 9 from that result (e.g., 16: 16 − 9 = 7, 18: 18 − 9 = 9) But your newly edited code does neither, and as such returns false for many valid numbers.

### tflori commented Sep 14, 2019

 @mogzol ah f**k.. thanks for the info 👍