L'algorithme de Luhn expliqué : comment fonctionne la validation d'un numéro de carte
Chaque numéro de carte que vous avez saisi dans un formulaire a été vérifié par un algorithme vieux de 70 ans avant de quitter votre navigateur. L'algorithme de Luhn — aussi appelé MOD 10 ou algorithme modulo 10 — est la somme de contrôle que tous les grands réseaux de cartes utilisent pour repérer les fautes de frappe. Ce guide explique comment il fonctionne, comment l'implémenter et ce qu'il ne peut pas faire.
Qu'est-ce que l'algorithme de Luhn ?
L'algorithme de Luhn a été inventé en 1954 par le chercheur d'IBM Hans Peter Luhn et breveté en 1960. C'est une formule de somme de contrôle simple qui détecte les erreurs accidentelles dans les numéros d'identification : erreurs sur un seul chiffre, la plupart des inversions de chiffres adjacents et quelques autres classes d'erreurs.
Ce n'est ni une mesure de sécurité, ni du chiffrement. C'est un contrôle d'intégrité des données. Les réseaux de cartes ajoutent un chiffre de contrôle de Luhn à chaque numéro de carte, et n'importe quel système peut le vérifier avec quelques lignes de code et aucun accès réseau.
Comment ça marche, étape par étape
Soit un nombre, par exemple 79927398713 :
- En partant du chiffre le plus à droite et en allant vers la gauche, doublez un chiffre sur deux.
- Si le doublement donne une valeur supérieure à 9, soustrayez 9 (ce qui équivaut à additionner les deux chiffres du résultat).
- Additionnez tous les chiffres — ceux qui ont été doublés comme les autres.
- Si le total est divisible par 10, le numéro passe le contrôle.
Pour 79927398713, la somme des chiffres traités vaut 70 : le numéro est donc valide.
Pour une vraie carte, le chiffre de contrôle n'est pas connu à l'avance : l'émetteur le calcule pour que le numéro final passe le contrôle. C'est pourquoi tout numéro de carte valide au monde satisfait la même condition d'une ligne : total % 10 === 0.
Implémentation
JavaScript
function isValidLuhn(number) {
const digits = number.replace(/\D/g, '');
let sum = 0;
let double = false;
for (let i = digits.length - 1; i >= 0; i--) {
let digit = Number(digits[i]);
if (double) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
double = !double;
}
return sum % 10 === 0;
}
Python
def is_valid_luhn(number: str) -> bool:
digits = [int(c) for c in number if c.isdigit()]
total = 0
for index, digit in enumerate(reversed(digits)):
if index % 2 == 1:
digit *= 2
if digit > 9:
digit -= 9
total += digit
return total % 10 == 0
PHP
function isValidLuhn(string $number): bool
{
$digits = preg_replace('/\D/', '', $number);
$sum = 0;
$double = false;
for ($i = strlen($digits) - 1; $i >= 0; $i--) {
$digit = (int) $digits[$i];
if ($double) {
$digit *= 2;
if ($digit > 9) {
$digit -= 9;
}
}
$sum += $digit;
$double = !$double;
}
return $sum % 10 === 0;
}
Vous pouvez tester n'importe quel numéro instantanément avec notre validateur de Luhn.
Ce que Luhn ne détecte pas
L'algorithme de Luhn est volontairement simple, ce qui le rend aussi facile à tromper :
- Il ne peut pas dire si une carte existe. N'importe quel numéro peut être rendu valide pour Luhn, y compris des numéros de BIN jamais émis. Luhn ne dit rien du compte, du solde ni de l'émetteur.
-
Il rate certaines inversions. Échanger
09et90donne la même somme ; cette inversion précise n'est donc pas détectée. La plupart des autres inversions de chiffres adjacents sont repérées. - Il ne valide ni la longueur ni le BIN. Les règles de longueur et les plages de BIN sont des contrôles distincts. Un numéro à 16 chiffres peut passer Luhn tout en étant invalide pour un BIN Amex à 15 chiffres.
- Ce n'est pas une fonction de sécurité. Les attaquants génèrent des numéros valides pour Luhn sans effort ; le contrôle sert à protéger les utilisateurs des fautes de frappe, pas les systèmes de la fraude.
Pourquoi les développeurs s'y intéressent
Si vous construisez quoi que ce soit qui accepte des données de carte, vous rencontrerez Luhn à au moins trois endroits :
- Validation côté client — donnez un retour immédiat à l'utilisateur avant l'envoi d'un formulaire et évitez un aller-retour vers votre prestataire de paiement pour une faute de frappe évidente.
- Génération de données de test — les fixtures, les seeds et les scripts de QA ont besoin de numéros qui passent la validation, donc le chiffre de contrôle doit être calculé correctement. C'est exactement ce que fait notre générateur de cartes de test.
- Parsing et normalisation — quand les numéros arrivent de clients, de tableurs ou de logs, Luhn est le contrôle de bon sens le moins coûteux avant d'envoyer quoi que ce soit à une passerelle.
Générer des numéros de test valides
Pour générer des numéros de test structurellement valides à partir de n'importe quel BIN, utilisez le générateur de cartes Namso Gen. Il calcule le chiffre de contrôle de Luhn pour vous et peut ajouter des dates d'expiration et des CVV. Si vous voulez énumérer toutes les combinaisons d'un motif, le générateur avancé accepte les jokers x.
Pour un tour complet des contrôles qui vont au-delà de Luhn, voir Les numéros BIN expliqués ou vérifiez n'importe quel préfixe avec le vérificateur de BIN.
Résumé
- Luhn (MOD 10) est une somme de contrôle, pas un contrôle de validité ni de sécurité.
- Doubler un chiffre sur deux en partant de la droite, additionner, puis tester la divisibilité par 10 : il n'y a rien d'autre.
- Tous les grands réseaux de cartes l'utilisent, c'est pourquoi tout vrai numéro de carte passe le contrôle.
- Utilisez-le pour détecter les fautes de frappe, jamais comme unique validation.