VERIFICATION D'UNE ADRESSE IP

Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 - 6 févr. 2009 à 23:37
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 - 12 févr. 2009 à 14:41
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/49200-verification-d-une-adresse-ip

Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
12 févr. 2009 à 14:41
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é.
cherifnet2002 Messages postés 6 Date d'inscription mardi 24 mai 2005 Statut Membre Dernière intervention 11 février 2009
11 févr. 2009 à 20:41
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.
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
9 févr. 2009 à 02:34
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.
cherifnet2002 Messages postés 6 Date d'inscription mardi 24 mai 2005 Statut Membre Dernière intervention 11 février 2009
8 févr. 2009 à 22:05
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 .
cs_New_World Messages postés 53 Date d'inscription mardi 15 août 2006 Statut Membre Dernière intervention 15 juillet 2010
7 févr. 2009 à 13:16
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 ?
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
6 févr. 2009 à 23:37
Tu ne serais pas mieux d'utiliser la fonction native de PHP ip2long pour faire cela ?

<?php
function in_plage($debut, $fin, $test) {
return (ip2long($test) < ip2long($fin) && ip2long($test) > ip2long($debut));
}
?>

Aussi avec ip2long tu peux mettre des adresses incomplète du genre 127.0.0 (qui va être interprété comme 127.0.0.0), ce qui peut être pratique pour les range de IP.
Rejoignez-nous