Contrôle siren/siret

Je n’ai pas trouvé en partage de code, alors si ça peut servir…
<code 4D>
//SIRET_ok (nombre_t) -> text
//$0 texte vide si le n° SIREN ou SIRET passé est valide
//le numéro à contrôler doit
// comporter uniquement des chiffres (0…9)
// et avoir une longueur 9 (SIREN) ou 14 (SIRET = SIRET+NIC)

//https://www.service-public.fr/professionnels-entreprises/vosdroits/F31190
//https://fr.wikipedia.org/wiki/Formule_de_Luhn
//http://blog.pagesd.info/post/2012/09/05/verifier-numero-siret-la-poste

//L’algorithme procède en trois étapes.
// 1 L’algorithme multiplie par 2 un chiffre sur deux, en commençant par l’avant dernier
// et en se déplaçant de droite à gauche.
// Si un chiffre qui est multiplié par 2 est plus grand que 9
// on lui soustrait 9
// 2 La somme de tous les chiffres obtenus est effectuée.
// 3 Le résultat est divisé par 10.
// Si le reste de la division est égal à 0,
// alors le nombre original est valide.

//En France, La Poste ne respecte pas l’algorithme de Luhn mais toutefois,
//il faut quand même vérifier si le Siret est valide.
//La poste a changé de statut et elle est devenue une société anonyme.
//Tous les établissements de La Poste possèdent un SIRET, sous cette forme : 356 000 000 #####.
//Comme La Poste a beaucoup d’établissements et que la plage de Siret (découlant du Siren)
// n’est pas assez grande, la règle de numérotation du Siret a été
// modifiée pour cette entreprise.
//Le nouvel algorithme de contrôle pour les Siret de la forme 356 000 000 ##### est le suivant :
//La somme simple des chiffres du SIRET doit être congrue à 0 modulo 5,
//c’est-à-dire qu’elle doit être un multiple de 5.

//© Bill * 17/11/2015
C_TEXTE($0)
C_TEXTE($1)

C_TEXTE($error_t)
C_ENTIER LONG($len_l)
C_ENTIER LONG($luhn_l)
C_ENTIER LONG($i_l)
C_ENTIER LONG($n_l)
C_TEXTE($str_t)
C_BOOLÉEN($OK_b)
//_
$error_t:=""
Au cas ou
: (Nombre de paramètres<1)
$error_t:=“Appel incorrect à la méthode “+Nom méthode courante+” $1 expected”
: ((Longueur($1)#9) & (Longueur($1)#14))
$error_t:=“Un numéro SIREN doit comporter 9 chiffres, un numéro SIRET 14 chiffres”
: (Non(Trouver regex("^\d{9,14}$";$1;1)))
$error_t:=“Un numéro SIREN doit comporter 9 chiffres, un numéro SIRET 14 chiffres”
Sinon
$OK_b:=Faux
$str_t:=$1
$len_l:=Longueur($str_t)
$luhn_l:=0
Si ($str_t=“356000000@”) & ($len_l=14) //SIRET de La Poste
Boucle ($i_l;1;$len_l)
$luhn_l:=$luhn_l+Num($str_t[$i_l])
Fin de boucle
$OK_b:=($luhn_l%5=0)
Sinon //SIRET d’autres entreprises que La Poste ou tous les SIREN
Boucle ($i_l;$len_l;1;-1)
$n_l:=Num($str_t[$i_l])
Si (($len_l-$i_l)%2=1)
$n_l:=$n_l*2
Si ($n_l>9)
$n_l:=$n_l-9
Fin de si
Fin de si
$luhn_l:=$luhn_l+$n_l
Fin de boucle
$OK_b:=($luhn_l%10=0)
Fin de si

Si (Non($OK_b))
Si ($len_l=9)
$error_t:=“Erreur dans le numéro SIREN, la clé de contrôle ne correspond pas”
Sinon
$error_t:=“Erreur dans le numéro SIRET, la clé de contrôle ne correspond pas”
Fin de si
Fin de si

Fin de cas
$0:=$error_t
//_
</code 4D>

Salut Arnaud,

J’ai un truc qui approche mais en décomposé (et je ne connaissais pas la spécificité de La Poste)…

CRC_luhnCheck
<code 4D>
//==============================================================================
//Methode projet : CRC_luhnCheck
// Publique
//
//DESCRIPTION :
// Cette fonction effectue une vérification d’un texte selon l’algorithme de clé de luhn (mod 10)
// http://en.wikipedia.org/wiki/Luhn_algorithm
//
// PARAMETRES :
// $0 (BOOLEAN) <= True, luhn checksum ok, False otherwise
// $1 (TEXT) => text with luhn checksum at the end
//
//NOTES :
//
//EXAMPLE D’APPEL :
// CRC_luhnCheck
//
//CREATION : Bruno LEGAY (BLE) - 15/04/09, 17:37:37 - v1.00.00
//
// 1999-2006 © A&C Consulting
//
===============================================================================

C_BOOLEEN($0;$vb_ok) //luhn checksum ok
C_TEXTE($1;$vt_text) //text with luhn checksum

$vb_ok:=Faux
Si (Nombre de parametres>0)
$vt_text:=$1

C_ENTIER LONG($vl_length)
$vl_length:=Longueur($vt_text)
Si ($vl_length>0)

C_ENTIER LONG($i;$vl_checksum;$vl_ascii)
$vl_checksum:=0

C_BOOLEEN($vb_odd)
$vb_odd:=Vrai //we will start with 1 which is odd

Boucle ($i;$vl_length;1;-1)
$vl_ascii:=Code de caractere($vt_text≤$i≥)

//check that it is a digit “0” to “9”
Si (($vl_ascii>=48) & ($vl_ascii<=57))
$vl_ascii:=$vl_ascii-48

Au cas ou
: ($vl_ascii=0)

: ($vb_odd) // odd
$vl_checksum:=$vl_checksum+$vl_ascii

: ($vl_ascii<5)
//$vl_ascii << 1 <=> $vl_ascii * 2
$vl_checksum:=$vl_checksum+($vl_ascii << 1)

Sinon
//$vl_ascii << 1 <=> $vl_ascii * 2
//$vl_ascii - 9 <=> “14” => “1” + “4”
// 10 => 10-9 => 1 <=> “1” + “0”
// 12 => 12-9 => 3 <=> “1” + “2”
// 14 => 14-9 => 5 <=> “1” + “4”
// 16 => 16-9 => 7 <=> “1” + “6”
// 18 => 18-9 => 9 <=> “1” + “8”
$vl_checksum:=$vl_checksum+($vl_ascii << 1)-9
Fin de cas

//invert odd : set odd => even, even => odd
$vb_odd:=Non($vb_odd)
Fin de si

Fin de boucle

$vb_ok:=(($vl_checksum%10)=0)
Fin de si

Fin de si
$0:=$vb_ok

</code 4D>

UTL_SirenCheck
<code 4D>
//==============================================================================
//Methode projet : UTL_SirenCheck
// Publique
//
//DESCRIPTION :
// Cette fonction vérifie un identifiant SIREN. Un SIREN vide sera condidéré invalide. Un SIREN avec espace sera considéré invalide.
//
// PARAMETRES :
// $0 (BOOLEAN) <= Vrai si lE SIREN est valide, Faux sinon
// $1 (TEXTE) => SIREN
//
//NOTES :
// Le SIREN est composé de 9 caractères :
// les 8 caractères + 1 checksum clé de luhn (8+1)
//
//EXAMPLE D’APPEL :
// validation de “340 635 358” :
// UTL_SirenCheck (“340635358”)
//
//CREATION : Bruno LEGAY (BLE) - 15/04/09, 16:24:53 - v1.00.00
//
// 1999-2006 © A&C Consulting
//
===============================================================================

C_BOOLEEN($0;$vb_ok)
C_TEXTE($1;$vt_siren)

$vb_ok:=Faux

Si (Nombre de parametres>0)
$vt_siren:=$1

Si (Longueur($vt_siren)=9)
$vb_ok:= CRC_luhnCheck ($vt_siren)
Fin de si

Fin de si

$0:=$vb_ok
</code 4D>

UTL_SiretCheck
<code 4D>
//==============================================================================
//Methode projet : UTL_SiretCheck
// Publique
//
//DESCRIPTION :
// Cette fonction vérifie un identifiant SIRET. Un SIRET vide sera condidéré invalide. Un SIRET avec espace sera considéré invalide.
//
// PARAMETRES :
// $0 (BOOLEAN) <= Vrai si lE SIRET est valide, Faux sinon
// $1 (TEXTE) => SIRET
//
//NOTES :
// Le SIRET est composé de 14 caractères :
// les 9 premiers sont le SIREN et son checksum clé de luhn (8+1)
// le 5 autres caractères sont une code additionel et un checksum clé de luhn global (4+1)
//
//EXAMPLE D’APPEL :
// validation de “340 635 358 00062”
// UTL_SiretCheck (“34063535800062”)
//
// ASSERT(UTL_SirenCheck (“356000000”))
// ASSERT(UTL_SiretCheck (“35600000049837”))
// ASSERT(UTL_SiretCheck (“34063535800062”))
//
//CREATION : Bruno LEGAY (BLE) - 15/04/09, 16:24:53 - v1.00.00
//
// 1999-2006 © A&C Consulting
//
===============================================================================

C_BOOLEEN($0;$vb_ok)
C_TEXTE($1;$vt_siret)

$vb_ok:=Faux

Si (Nombre de parametres>0)
$vt_siret:=$1

Si (Longueur($vt_siret)=14)

Au cas ou
: ($vt_siret=“356000000@”) // le siret/siren de “La Poste” - cas particulier
// http://blog.pagesd.info/2012/09/05/verifier-numero-siret-poste/
// Le nouvel algorithme de contrôle pour les Siret de la forme 356 000 000 XXXXX est le suivant
// La somme simple des chiffres du SIRET doit être congrue à 0 modulo 5, c’est à dire qu’elle doit être un multiple de 5.
// Ce nouvel algorithme permet d’immatriculer jusqu’à 18 000 établissements environ, soit presque deux fois plus que dans le cas général, tout en maintenant un contrôle sur l’identifiant.

C_ENTIER LONG($i;$vl_ascii;$vl_checksum)
$vl_checksum:=0
Boucle ($i;1;Longueur($vt_siret))
$vl_ascii:=Code de caractere($vt_siret≤$i≥)

//check that it is a digit “0” to “9”
Si (($vl_ascii>=48) & ($vl_ascii<=57))
$vl_ascii:=$vl_ascii-48

$vl_checksum:=$vl_checksum+$vl_ascii
Fin de si

Fin de boucle
$vb_ok:=(($vl_checksum%5)=0)

Sinon
$vb_ok:=(CRC_luhnCheck ($vt_siret) & UTL_SirenCheck (Sous chaine($vt_siret;1;9)))
Fin de cas

Fin de si

Fin de si

$0:=$vb_ok
</code 4D>