-
-
Save troelskn/1287893 to your computer and use it in GitHub Desktop.
<?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; | |
} |
In case anyone tries using @mogzol solution while working with the Luhn algorithm applied to a base higher than 10, for example to validate an alphanumeric string where each character can go from 0-9 or A-Z, meaning its value ranges from 0-36, you need to be more careful performing the total sum.
In the solution, when we're doing the total sum we are essentially ignoring the fact that Luhn algorithm only wants you to subtract 9 to values that have been doubled. It works for base 10 only because values that have not been doubled can't possibly be greater than 9.
To correctly implement a general any-base Luhn algorithm, you don't have this luxury, and must therefore apply both the doubling of the value and subsequent subtraction only IF the condition is met, in this case ($flag++ & 1), which by the way is quite an unreadable way to flip between true and false.
Here's a general readable example, assuming some valid string $number in base $base
$flip = false;
$sum = 0;
for ($i = strlen($number) - 1; $i >= 0; $i--) {
$value = intval($number[$i], $base);
if($flip){
$value = $value * 2;
$value = $value > 9 ? $value - 9 : $value;
}
$sum += $value;
$flip = !$flip;
}
return $sum % 10 === 0;
Hi, this is my implementation: https://github.com/danielebarbaro/laravel-vat-eu-validator/blob/26e65de7df083e729b44e0ece02483dc6076bc71/src/VatValidator.php#L124
it works since 2019 🤓
@mogzol ah f**k.. thanks for the info 👍