fonction de Luhn en php « Site de Francis Hilaire étudiant à Supinfo Orléans : prometee-creation.com

Développement, PHP, Tutoriels : fonction de Luhn en php

feed Flux RSS des commentaires
Ecrit par Francis Hilaire, le Dimanche 9 mars, 2008

Après avoir regarder du côté de wikipédia, j’ai pu facilement construire la fonction de Luhn permettant entre autre de vérifier des numéros de carte bancaire.

//Fonction algorithme de Luhn
function isLuhnNum($num)
{
	//longueur de la chaine $num
	$length = strlen($num);

	//resultat de l'addition de tous les chiffres
	$tot = 0;
	for($i=$length-1;$i>=0;$i--)
	{
		$digit = substr($num, $i, 1);

		if ((($length - $i) % 2) == 0)
		{
			$digit = $digit*2;
			if ($digit>9)
			{
				$digit = $digit-9;
			}
		}
		$tot += $digit;
	}

	return (($tot % 10) == 0);
}

Merci à Andras pour sa précision ;)



Dernière modification le Mardi 14 octobre, 2008

6 Commentaires pour “ fonction de Luhn en php”

  1. Xfigpower a dit :

    Moi, j’utilise perso une version plus courte (je n’aime pas beaucoup le « -9″ dans l’algo)

    //Fonction algorithme de Luhn
    function isCB($numCB)
    {
    //longueur de la chaine $numCB
    $lengthCB = strlen($numCB);

    //resultat de l’addition de tous les chiffres
    $tot = 0;

    for($i=$lengthCB-1;$i>=0;$i–)
    {
    $digit = $numCB[$i];

    $tot += ($i % 2)?((2*$digit)%10 + (2*$digit)/10):$digit;
    }

    return !($tot % 10);
    }

    13 mars, 2008 à 13:38

  2. Francis Hilaire a dit :

    Moi c’est le (2*$digit)/10 qui me gène, ça donne forcément un float lorsque tu fais par exemple $digit = 1; Si tu travailles comme ça dans un autre language tel que Java ou C# ça ne passera jamais. Bon il est vrai que là on est censé recevoir un int et qu’on l’interprète comme un string donc bon…

    Le -9 est déjà plus mathématique car on a forcément un chiffre compris entre 0 et 18 lorsqu’on multiplie par 2 $digit et qu’il correspond exactement à ce que l’algorithme doit faire.

    C’est clair, c’est plus rapide, mais pas à comprendre pour un néophyte…

    13 mars, 2008 à 18:17

  3. andras a dit :

    hum, il me semble bien qu’il y a une erreur dans ton implementation : ça ne marche qu’avec les nombres qui ont un nombre de chiffre pair (comme les CB) mais pas avec ceux qui ont un nombre de chiffres impair (comme les numéros SIREN).

    il faut remplacer la ligne :
    if (($i % 2) == 0)
    par la ligne suivante :
    if ((($length – $i) % 2) == 0)

    et là, ça marche pour tous les cas, il me semble.

    9 juin, 2008 à 14:59

  4. Francis Hilaire a dit :

    Merci pour cette précision Andras ;)

    9 juin, 2008 à 19:15

  5. Melnofil a dit :

    Francis Hilaire :
    J’ai eu du mal à voir du premier coup comment circule la variable « $ret » tout au long de ton programme, pourquoi ne pas utiliser tout simplement :
    return ($tot % 10 == 0);

    As-tu une raison particulière d’appeler la fonction « substr » au lieu de l’opérateur « crochets » ?
    $digit = $num[$i];

    Xfigpower :
    Je paraphrase Francis Hilaire en ajoutant que la division est généralement l’opération de base la plus couteuse en temps processeur (quelque soit le language ou le processeur utilisé). Pire, ta multiplication par 2 est effectuée deux fois de suite pour rien !

    14 octobre, 2008 à 15:02

  6. Francis Hilaire a dit :

    Melnofil : Merci de ton intervention, j’avoue que c’est l’habitude qui m’as fait mettre ce $ret… Il est vrai qu’il est complètement inutile.

    14 octobre, 2008 à 15:09

Nouveau Commentaire

Laissez une réponse

(requis)

(requis)

XHTML: Vous pouvez utilisez ces balises: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>