Verification d'une adresse ip

Soyez le premier à donner votre avis sur cette source.

Snippet vu 7 391 fois - Téléchargée 15 fois

Contenu du snippet

Verification si une adresse IP [$atester] est a l'intérieur d'une plage d'adresses donnée [$debut,$fin].

ce code a été crée pour améliorer le code source de
New_World mis sur le site le 30/01/2009.

Source / Exemple :


<?php
/*
Verification si une adresse IP est a l'intérieur d'une plage
d'adresses donnée. Version Cherif BENBARCHE . 06 Fev 2009 .

  • /
function in_plage($debut, $fin, $atester) { $x = explode(".", $debut); $y = explode(".", $fin); $z = explode(".", $atester); // test de la correction des adresses fournies $correct = 0 ; for( $i = 0; $i < 4; $i++ ) { $correct += (($x[$i] >= 0) AND ($x[$i] <= 255)) ? 1 : 0 ; $correct += (($y[$i] >= 0) AND ($y[$i] <= 255)) ? 1 : 0 ; $correct += (($z[$i] >= 0) AND ($z[$i] <= 255)) ? 1 : 0 ; } // conversion decimale des adresses IP fournies si toutes sont correctes if( $correct == 12) { $dec_debut = $x[0] * 16777216 + $x[1] * 65536 + $x[2] * 256 + $x[3] ; $dec_fin = $y[0] * 16777216 + $y[1] * 65536 + $y[2] * 256 + $y[3] ; $dec_atester = $z[0] * 16777216 + $z[1] * 65536 + $z[2] * 256 + $z[3] ; // test de l'inclusion de l'adresse IP a tester à l'interieur de la plage spécifiée $incluse = ( $dec_atester >= $dec_debut AND $dec_atester <= $dec_fin) ? TRUE : FALSE ; return $incluse ; } else print "Il y a ". intval(12 - $correct)."<b> erreur(s)</b> dans les adresses fournies.<br>"; } // end function in_plage // test de la fonction in_plage $debut = "192.168. 0. 0"; $fin = "192.168.255.255"; $atester = "192.168. 0.137"; $resultat = in_plage( $debut, $fin, $atester ); $string = $resultat ? " figure " : " ne figure pas "; echo "L'adresse IP <b>".$atester.$string."</b>dans la plage ".$debut." à ".$fin ; ?>

Conclusion :


Ce code peut servir de base à diverses manipulations
d'adresses IP.
Bon courage.
Version 1.0 - 06 Fev 2009 .
BENBARCHE

A voir également

Ajouter un commentaire Commentaires
Messages postés
1044
Date d'inscription
lundi 7 mars 2005
Statut
Membre
Dernière intervention
13 juillet 2010
7
Ce que tu montres ce n'est pas une question de fiabilité. Le deuxième IP est erroné en synthaxe et ip2long retourne FALSE pour un ip invalide. C'est encore une fois un comportement normal et prévu tel qu'indiqué dans la documentation que tu peux trouver sur php.net. D'autant plus qu'il n'existe théoriquement aucun cas ou tu vas avoir en entrée un adresse IP avec un espace.

Pour les nombres négatifs, c'est que ip2long retourne un entier signé. Pour le convertir en entier non-signé il existe une façon très simple :

if (($lngIP=ip2long($strIP)) < 0){$lngIP += 4294967296 ;}

En théorie le nombre retourné est bon, c'est simplement qu'il est mal interprété.
Messages postés
6
Date d'inscription
mardi 24 mai 2005
Statut
Membre
Dernière intervention
11 février 2009

Je suis d'accord pour le benchmark, et c'est l'appel
légitime de la fonction explode à la ligne 21, à
l'interieur de la boucle FOR, qui est en grande partie
responsable d'un tel écart.

Par contre la fonction ip2long me cause quelques
soucis, par exemple ce test avec ce qui est à peu
près la meme adresse IP :
---------------------------------
<?php
$adresse1 = "192.168.41.201";
$adresse2 = "192.168. 41.201";
$dec_adresse1 = ip2long($adresse1);
$dec_adresse2 = ip2long($adresse2);
echo "IP : ".$adresse1 ." valeur decimale : ".$dec_adresse1."
";
echo "IP : ".$adresse2 ." valeur decimale : ".$dec_adresse2."
";
echo ($dec_adresse1 ? "VRAI
":"FAUX
");
echo ($dec_adresse2 ? "VRAI":"FAUX");
?>
---------------------------------
me donne les résultats suivants :

IP : 192.168.41.201 valeur decimale : -1062721079
IP : 192.168. 41.201 valeur decimale :
VRAI
FAUX

soit une valeur decimale négative inacceptable et un testlogique VRAI, ainsi que pas de valeur décimale et un test logique FAUX.

Pour finir, j'aimerais bien voir une solution COMPLETE et FIABLE avec la fonction ip2long à la question initiale posée :
VERIFICATION QU'UNE ADRESSE IP DONNEE EST INCLUSE OU NON DANS UNE PLAGE D'ADRESSE DONNEE.

En remerciant d'avance toutes les propositions.
Messages postés
1044
Date d'inscription
lundi 7 mars 2005
Statut
Membre
Dernière intervention
13 juillet 2010
7
Quelques corrections à faire dans ce que cherifnet2002 a dit :

"Bien sur, ce calcul peut etre fait en appelant la fonction ip2long mais je
prefère faire le calcul directement, car l'appel de toute fonction est
couteux en cycles processeur"

Même si le fait d'appeler une méthode demande une opération au processeur, le fait que la fonction native s'exécuter beaucoup plus rapidement compense assez pour que le même code s'exécute environ 3 à 4 fois plus rapidement. Pour un language plus bas niveau comme le C/C++ ce que tu dis est vrai, mais pas pour des languages assez haut niveau comme PHP. Voici un benchmark assez simple pour montrer cela :

Source : http://pastebin.com/m411e64d2

Résultat sur un serveur Apache 2.0.63 avec PHP 5.2.3 qui roule sur une machine Windows (avec processeur Intel) en locale :

Test #0 :
Temps pour ip2long : 1.7627670764923
Temps avec convertion manuelle : 6.8783991336823

Test #1 :
Temps pour ip2long : 1.7135169506073
Temps avec convertion manuelle : 6.823725938797

En plus la méthode ip2long te retourne false si l'adresse est invalide ce que la méthode manuelle ne fait pas.

"et cette fonction apprehende mal l'adresse,
trés peu utilisée il est vrai, 255.255.255.255. (cf. manuel_php)."

«Note: ip2long() devrait retourner FALSE pour l'adresse IP 255.255.255.255 en PHP 5 <= 5.0.2. Ce comportement a été modifié en PHP 5.0.3 où il retournait -1 (comme en PHP 4).» (Source : http://ca2.php.net/manual/fr/function.ip2long.php)

Si tu lis correctement, tu remarqueras que pour l'adresse 255.255.255.255 c'est un comportement qui est voulu et que ce n'est pas parce qu'il "apprehende mal" l'adresse.
Messages postés
6
Date d'inscription
mardi 24 mai 2005
Statut
Membre
Dernière intervention
11 février 2009

Bonjour à tous.
Par convention (dite dot-decimal notation, ou encore dotted quad notation),
on écrit généralement une adresse IPv4 en considérant chaque octet
comme un entier non signé, donc ayant une valeur de 0 à 255 (28 -1),
en séparant les valeurs des quatre octets par des points, et en ordonnant
de l'octet ayant le poids le plus fort à celui de poids le plus faible.

Il y a donc au maximum 2^32 soit 4 294 967 296 adresses IPv4 possibles.
voir la page http://fr.wikipedia.org/wiki/Adresse_IPv4

Par exemple, pour l'adresse convertir 192.168.41.201 en decimal il faut faire
le calcul suivant :
192 * 256^3 192 * 16777216 3221225472
+ 168 * 256^2 168 * 65536 11010048
+ 41 * 256 = 10496
+ 201 = 201
----------
soit un total de = 3232246217 pour cette adresse.

Bien sur, ce calcul peut etre fait en appelant la fonction ip2long mais je
prefère faire le calcul directement, car l'appel de toute fonction est
couteux en cycles processeur et cette fonction apprehende mal l'adresse,
trés peu utilisée il est vrai, 255.255.255.255. (cf. manuel_php).

De plus, ma manière de faire peut servir pour d'autres langages ( Delphi,
C++, Perl, Python...) et est plus pédagogique et c'est pour cela que je
n'ai pas voulu utiliser d'autres formes teintées d'"ésotérisme" et qui
fonctionnent tout aussi bien :
// ...
define("pow256_3", 16777216 );
define("pow256_2", 65536 );

$dec_debut = $x[0] * pow(256,3) + $x[1] * pow(256,2) + $x[2] * 256 + $x[3];
$dec_fin = $y[0] * pow256_3 + $y[1] * pow256_2 + $y[2] * 256 + $y[3];
$dec_atester = ((($z[0]<<24) | ($z[1]<<16) | ($z[2]<<8) | $z[3] ) & 0x7FFFFFFF ) + 0x80000000 ;
// ...
En souhaitant que ce code et ces explications
puissent etre utiles à quelqu'un. Amicalement .
Messages postés
53
Date d'inscription
mardi 15 août 2006
Statut
Membre
Dernière intervention
15 juillet 2010

bonjour

merci pour ton code j'ai pas verifié mais ça l'air de bien marché ;) .
en fait j'ai une question :-) pourquoi tu as mis $x[0] * 16777216 + $x[1] * 65536 + $x[2] * 256 + $x[3] pour la convertion j ai pas bien pigé et pourquoi tu n'a pas utiliser ip2long a t il un convenion qu'on connais pas ?
Afficher les 6 commentaires

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.