Contrôle de la conformité d'un numéro de carte bancaire (algorithme de luhn)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 24 880 fois - Téléchargée 16 fois

Contenu du snippet

Voici une fonction simple qui permet de contrôler la conformité d'un numéro de carte bancaire.

Il suffit de passer en paramètre les 16 chiffres de la carte et la fonction renverra true si le numéro est conforme et false si il n'est pas conforme.

Cette fonction utilise l'algorithme de LUHN pour tester la conformité du numéro.

Attention : Cette fonction ne garantie pas que le numéro de carte bancaire est valide. Un numéro peut être conforme mais pas forcément valide. Seul un établissement bancaire pourra garantir la validité d'un numéro.

Source / Exemple :


<?php
	/**

  • Test la conformité d'un numéro de carte bancaire.
*
  • @param string $num
  • /
function test_cb($num){ if(strlen($num) == 16){ // 16 caractères // Séparation de tous les caractères $c = array(); for($i=0; $i<16; $i++){ if(is_numeric(substr($num,$i,1))){ // Uniquement des chiffres $c[$i] = substr($num,$i,1); }else{ return false; } } // Contrôle $m1 = 0; for($i=0; $i<16; $i++){ if(($i%2)==0){ $x = $c[$i]*2; if($x>9){ $m1 += $x-9; }else{ $m1 += $x; } }else{ $m1 += $c[$i]; } } if(($m1%10)!=0){ // Doit être multiple de 10 return false; } // Pas d'erreur return true; }else{ return false; } } ?>

A voir également

Ajouter un commentaire

Commentaires

verdy_p
Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

Concernant les longueurs de numéros, on a aussi 17 chiffres (6 pour l'émetteur, plus 10 pour le numéro de carte, plus 1 pour la clé) dans les cartes S'Miles par exemple.

Pour les cartes de crédit revolving comme Aurore, on a un autre format à 19 chiffres (6 pour l'émetteur, plus 10 pour le numéro de compte carte, plus 3 pour l'index de la carte et la clé); je n'ai pas vérifié si l'algo de Luhn était utilisé pour ces cartes et il est probable qu'il y a d'autres sommes de contrôle cachées dans certaines composantes, comme c'est aussi le cas pour les numéros de compte bancaire

Pour les cartes CB émises par certaines banques on a le même problème car 16 chiffres sont insuffisants pour éviter l'utilisation abusive ou accidentelle de codes existants: c'est la raison pour laquelle les numéros de carte à 16 chiffres ont maintenant une extension à 3 ou 4 chiffres imprimé derrière la carte dans la zone de signature, un autre numéro de contrôle de validité destiné à renforcer le code de Luhn et à vérifier la période de validité d'une carte émise quand il y en aura plusieurs pour le même compte).
verdy_p
Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

Excuse moi Seb, mais tu te trompes d'interlocuteur (et je me trompe aussi): mes commentaires postés ici ne concernais QUE le code de la réponse donnée par FS074995: c'est ce code qui est faux, et c'est LUI (enfin plutôt son code) que j'ai critiqué, pas toi. D'ailleurs je l'avais indiqué très explicitement dans ma première réponse à ce sujet en le nommant dans le deuxième mot. Mes corrections concernaient SON code, pas le tien qui est correct (même s'il est un peu lourd et n'explote pas complètement la syntaxe PHP et contient plusieurs RETURN).

Dans la correction que j'ai postée, je ne teste pas la longueur (16) car je ne suppose pas que l'algo est réservé aux numéros de cartes bancaires (à ce sujet, il y a des numéros de carte à 13 ou 15 chiffres, et même des cartes de crédit à 20 chiffres...), mais il fonctionne aussi pour certains numéros de comptes bancaires (mais pas les RIB français qui utilisent une somme modulo 97, des chiffres groupés par 6 depuis la gauche, la clé RIB à deux chiffres étant entre 01 et 97 où 97 remplace 00 dans les clés réelles, ce qui ne change rien au modulo 97, ni les numéros IBAN qui utilisent un algorithme modifié là aussi pour accepter les lettres).
verdy_p
Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

Lignes 10 et 18, il faut tout te dire ! Franchement il n'y a pas 10 000 endroits. Quand on ne veut pas regarder...

C'est toi qui ne veux pas lire ton propre texte, et qui "crache". Reconnais que tu t'es trompé (moi-même j'ai aussitôt admis m'être trompé dans le premier jet dans le deuxième code édité un peu trop vite, en omettant deux parenthèses, mais je me suis corrigé; je peux aussi faire des erreurs, mais ton problème est que tu n'admets pas les tiennes).

Ton code est faux car il n'acceptera QUE un numéro entièrement fait de zéros. Pour tous les autres, la division du chiffre par 12 en PH est une division flottante qui retournera un entier un un entier plus un demi, donc différente de zéro (donc le code dans le "if" ne sera pas exécuté) et le chiffre ne sera pas doublé. Tous les chiffres seront donc simplement ajoutés les uns aux autres dans la boucle (aucun ne sera doublé sauf les zéros où c'est sans effet). Dans la dernière ligne la division par 10 est également flottante et divisera la somme des chiffres par 10. Cette division ne sera nulle que si la somme des chiffres est elle-même nulle. De fait ton code ne retourne 0 (OK) que si la somme des chiffres (produite par la boucle) est nulle, donc si tous les chiffres sont nuls. CQFD.

Ton code est donc inutilisable car tu as confondu la division "/" avec le modulo "%" demandé dans les deux lignes: c'est bien un modulo qu'il faut utiliser pour tester la parité (on peut aussi utiliser "x & 1" au lieu de "x % 2"), et pour tester si la somme est un multiple de 10; la division est hors de propos.
Seb33300
Messages postés
16
Date d'inscription
dimanche 9 avril 2006
Statut
Membre
Dernière intervention
25 janvier 2011

Quelle ligne... ?

Plutôt que de dire n'importe quoi tu ferais mieux de lire et tester le code avant de me cracher dessus.
verdy_p
Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

tu as mis « / 2 » et « / 10 » au lieu de « % 2 » et « % 10 » !

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.