For­mule de Luhn

For­mule de Luhn

sam 16 février 2019 0 Par Ibmiiste

Petite défi­ni­tion de la Luhn

La for­mule de Luhn per­met de véri­fier la vali­di­té d’une suite de chiffre. Ex:SIREN, N°CB, N°PS (Méde­cin pra­ti­cien, etc…). Le nombre est lu de droite à gauche. Les chiffres en posi­tion impaire res­tent tel quel et les chiffres en posi­tion paire sont mul­ti­pliées par 2. Tous les chiffres résul­tants sont ajou­té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 vali­dé si le résul­tat est divi­sible par 10. Dans l’exemple pré­cé­dent, le nombre n’est pas valide ; 11 n’est pas divi­sible par 10. Un nombre valide est par exemple 455. 

Coding

Voi­ci ci-des­sous, une pro­cé­dure écrite pour véri­fier un nombre selon la for­mule de Luhn. Elle est com­po­sée d’une pro­cé­dure prin­ci­pale et 2 sous-procédures. 

La sous-pro­cé­dure CALCUL déter­mine le résul­tat des addi­tions suc­ces­sives. Remarque : dans le cas du cal­cul des posi­tions paires, une autre règle a été appli­quée sur les résul­tats supé­rieurs à 9. La somme des chiffres obte­nus est égale à la mul­ti­pli­ca­tion 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-pro­cé­dure PARITE déter­mine 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 e 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