Petite définition de la Luhn
La formule de Luhn permet de vérifier la validité d’une suite de chiffre. Ex:SIREN, N°CB, N°PS (Médecin praticien, etc…). Le nombre est lu de droite à gauche. Les chiffres en position impaire restent tel quel et les chiffres en position paire sont multipliées par 2. Tous les chiffres résultants sont ajoutés. Exemple 456 :
Chiffres 4 5 6
Position 3 2 1
Résultats 4 10 6
Résultat 4 + 1 + 0 + 6 = 11
Un nombre Luhn est validé si le résultat est divisible par 10. Dans l’exemple précédent, le nombre n’est pas valide ; 11 n’est pas divisible par 10. Un nombre valide est par exemple 455.
Coding
Voici ci-dessous, une procédure écrite pour vérifier un nombre selon la formule de Luhn. Elle est composée d’une procédure principale et 2 sous-procédures.
La sous-procédure CALCUL détermine le résultat des additions successives. Remarque : dans le cas du calcul des positions paires, une autre règle a été appliquée sur les résultats supérieurs à 9. La somme des chiffres obtenus est égale à la multiplication par 2 moins 9.
5x2=10 Résultat 1+0=1 mais aussi 5x2-9=1
6x2=12 Résultat 1+2=3 mais aussi 6x2-9=3
7x2=14 Résultat 1+4=5 mais aussi 7x2-9=5
8x2=16 Résultat 1+6=7 mais aussi 8x2-9=7
9x2=18 Résultat 1+8=9 mais aussi 9x2-9=9
La sous-procédure PARITE détermine si un chiffre est pair ou impair.
h nomain
dVerif_Luhn PR N
d a_Nombre_Luhn 32768A OPTIONS(*VARSIZE) CONST
dCalcul PR 6 0
d a_Nombre_Luhn 32768A OPTIONS(*VARSIZE) CONST
d a_longueur 5i 0
D*--------------------------------------------------
D* Procedure name: parite
D* Purpose: Déterminer si un nombre est pair ou impair
D* Returns:
D* Parameter: a_nombre => Nombre dont on vérifie la parité
D*--------------------------------------------------
Dparite PR N
D a_nombre 6P 0 value
pVerif_Luhn b Export
dVerif_Luhn PI N
dg_nbre_luhn 32768A OPTIONS(*VARSIZE) CONST
d g_longueur s 5i 0
d g_valid s 1 0
d g_luhn s N
d g_Nombre_Luhn s 20A Varying
/free
g_Nombre_Luhn=%trim(g_nbre_luhn);
g_longueur=%len(%trim(g_Nombre_Luhn));
g_valid=%rem( calcul(g_Nombre_Luhn:g_longueur):10);
If g_valid=0;
g_Luhn=*on;
Else;
g_Luhn=*off;
ENDIF;
Return g_Luhn;
/end-free
pVerif_Luhn e
pcalcul b
dCalcul PI 6 0
d l_Nombre_Luhn 32768A OPTIONS(*VARSIZE) CONST
d l_longueur 5i 0
d l_pos s 5i 0
d l_total s 6 0
d l_ajout s 2 0
/free
FOR l_pos = l_longueur DOWNTO 1;
// Le corps de la boucle va ici
l_ajout=%dec(%subst(l_Nombre_Luhn:l_pos:1):2:0);
if parite(l_pos);
l_ajout=l_ajout*2;
if l_ajout>9;
l_ajout=l_ajout-9;
ENDIF;
ENDIF;
l_total=l_total+l_ajout;
ENDFOR;
return l_total;
/end-free
pcalcul e
P*--------------------------------------------------
P* Procedure name: parite
P* Purpose: Déterminer di un nombre est pair ou impair
P* Returns:
P* Parameter: a_nombre => Nombre dont on vérifie la parité
P*--------------------------------------------------
P parite B
D parite PI N
D l_nombre 6P 0 value
D* Local fields
D l_reste s 1 0
d l_pair s N inz(*off)
/FREE
l_reste= %rem( l_nombre:2);
if l_reste=0;
l_pair=*on;
ENDIF;
RETURN l_pair;
/END-FREE
P parite E