Demo for Luhn algorithm in PHP
20060224 12:30 by javierIf you have a number that adheres to the Luhn algorithm for validation, you may check it easily with this short PHP snippet.
<?php
function luhn($str) {
$odd = !strlen($str)%2;
$sum = 0;
for($i=0;$i<strlen($str);++$i) {
$n=0+$str[$i];
$odd=!$odd;
if($odd) {
$sum+=$n;
} else {
$x=2*$n;
$sum+=$x>9?$x-9:$x;
}
}
return(($sum%10)==0);
}
$num = $_GET[‘number’];
?>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html>
<head>
<title>Online Luhn algorithm test</title>
<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1″>
</head>
<body>
<?php if($num) { ?>
<?php if(luhn($num)) { ?>
<div style=“background:#ddffdd;border:1px solid #004400;”>
<?=htmlspecialchars($num)?> is valid
</div>
<?php } else { ?>
<div style=“background:#ffdddd;border:1px solid #880000;”>
<?=htmlspecialchars($num)?> is NOT valid
</div>
<?php } ?>
<?php } ?>
<form action=“luhn.php” method=“GET”>
<div>
Number: <input type=“text” name=“number” value=“<?=urlencode($num)?>” size=“40″/>
<input type=“button” name=“btSend” value=“Check”/>
</div>
</form>
</body>
function luhn($str) {
$odd = !strlen($str)%2;
$sum = 0;
for($i=0;$i<strlen($str);++$i) {
$n=0+$str[$i];
$odd=!$odd;
if($odd) {
$sum+=$n;
} else {
$x=2*$n;
$sum+=$x>9?$x-9:$x;
}
}
return(($sum%10)==0);
}
$num = $_GET[‘number’];
?>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html>
<head>
<title>Online Luhn algorithm test</title>
<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1″>
</head>
<body>
<?php if($num) { ?>
<?php if(luhn($num)) { ?>
<div style=“background:#ddffdd;border:1px solid #004400;”>
<?=htmlspecialchars($num)?> is valid
</div>
<?php } else { ?>
<div style=“background:#ffdddd;border:1px solid #880000;”>
<?=htmlspecialchars($num)?> is NOT valid
</div>
<?php } ?>
<?php } ?>
<form action=“luhn.php” method=“GET”>
<div>
Number: <input type=“text” name=“number” value=“<?=urlencode($num)?>” size=“40″/>
<input type=“button” name=“btSend” value=“Check”/>
</div>
</form>
</body>
(Download)
You may test this script at http://javier.rodriguez.org.mx/code/luhn-test.php.
Please consider that this is a demo, so please do not use this to check credit card numbers unless you send me an expiry date. CCV2 has taken over as the preferred method for credit card number validation anyway.

















May 2nd, 2006 at 21:54
Amigo: a ese ejemplo ponele un submit, pone en lugar de : name=”num” y saca el ACTION que esta de mas y confunde, porque de lo contrario, ese ejemplo no va a funcionar en la puta vida. Un fuerte a abrazo, y de todos modos: GRACIAS!
May 2nd, 2006 at 21:56
Un agregado, para que aclare mi mensaje anterior: la linea
$num = $_GET['number'];
no esta funcionando correctamente, de hecho, en tu ejemplo web no funciona.
Nos vemos, amigo.
May 30th, 2007 at 12:24
I don’t think your algorithm is correct. Among others, it fails on the test Visa number: 4111111111111111.
-L
July 14th, 2008 at 17:04
I agree with Lawrence your algorithm doesn’t validate
Thanks,
Mike
August 18th, 2008 at 13:37
Here is a (RIGHT-CODED & STRICT) Algorithm … ( do not delete my postings =/ ) it’s your content. But may if you do not want to have qualitiv content – delete it. For German Bankaccounts see the national bank (Deutsche Bundesbank)
… think big ppl ;)
/**
* Luhn-Algorithm for Creditcards an Bankaccounts
* Creditcards exposure is everytime 1212… in length of the cardnumber
* Banknumbers will have for each bank a own exposure.
* I hope all Verificationnumbers will be calculatet for Bankaccounts with this algorithm.
* In Some Cases the modulo have to be changed. On Creditcards the module everytime is 10.
* Please report bugs to doubleatdumpitde.
*
* @param string $nb have to be string and numeric because double is to small
* @param string $exp have to be string and numeric because double is to small
* @param int $mod used modulo
* @return boolean
*/
function _luhn( $nb, $exp = ‘1212121212121212′, $mod = 10 )
{
// first validate parameters
if( !is_string( $nb ) )
return PEAR::raiseError( ‘given parameter nb (number) is not a string’, null );
if( !is_string( $exp ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not a string’, null );
if( !is_numeric( $nb ) )
return PEAR::raiseError( ‘given parameter nb (number) is not numeric’, null );
if( !is_numeric( $exp ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not numeric’, null );
if( !is_integer( $mod ) )
return PEAR::raiseError( ‘given parameter mod (modulo) is not numeric’, null );
if( 0 >= $int )
return PEAR::raiseError( ‘given parameter nb (number) could not be lower than or zero’, null );
if( strlen($exp) != strlen( $int ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not in characterlength of nb (number)’, null );
// lets do the calculation
for( $sum = 0, $pos = 0; $pos = $x ? $x : $x[0]+$x[1];
}
return(0==$sum%$mod);
}
August 18th, 2008 at 13:39
??
August 18th, 2008 at 14:06
Ok, Sry ppl, here is the debuged (working) version … a new try to post.
Maybe the calculation have to be done recursive (see wikipedia)
/**
* Luhn-Algorithm for Creditcards an Bankaccounts
* Creditcards exposure is everytime 2121… in length of the cardnumber
* Banknumbers will have for each bank a own exposure.
* I hope all Verificationnumbers will be calculatet for Bankaccounts with this algorithm.
* In Some Cases the modulo have to be changed. On Creditcards the module everytime is 10.
* Please report bugs to doubleatdumpitde
*
* @param string $nb have to be string and numeric because double is to small
* @param string $exp have to be string and numeric because double is to small
* @param int $mod used modulo
* @return boolean
*/
function _luhn( $nb, $exp = ‘2121212121212121′, $mod = 10 )
{
// first validate parameters
if( !is_string( $nb ) )
return PEAR::raiseError( ‘given parameter nb (number) is not a string’, null );
if( !is_string( $exp ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not a string’, null );
if( !is_numeric( $nb ) )
return PEAR::raiseError( ‘given parameter nb (number) is not numeric’, null );
if( !is_numeric( $exp ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not numeric’, null );
if( !is_integer( $mod ) )
return PEAR::raiseError( ‘given parameter mod (modulo) is not numeric’, null );
if( 0 >= $nb )
return PEAR::raiseError( ‘given parameter nb (number) could not be lower than or zero’, null );
if( strlen($exp) != strlen( $nb ) )
return PEAR::raiseError( ‘given parameter exp (exposure) is not in characterlength of nb (number)’, null );
// lets do the calculation
for( $sum = 0, $pos = 0; $pos < strlen( $nb ); $pos++ )
{
$x = $exp[$pos]*$nb[$pos];
$sum += 9 > $x ? $x : substr($x,0,1)+substr($x,1,1);
}
return(0<$sum&&0==$sum%$mod);
}
isn’t it easy ;)