Arto_8000
Messages postés1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 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és6Date d'inscriptionmardi 24 mai 2005StatutMembreDernière intervention11 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és1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 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 :
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és6Date d'inscriptionmardi 24 mai 2005StatutMembreDernière intervention11 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.
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és53Date d'inscriptionmardi 15 août 2006StatutMembreDernière intervention15 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és1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 6 févr. 2009 à 23:37
Tu ne serais pas mieux d'utiliser la fonction native de PHP ip2long pour faire cela ?
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.
12 févr. 2009 à 14:41
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é.
11 févr. 2009 à 20:41
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.
9 févr. 2009 à 02:34
"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.
8 févr. 2009 à 22:05
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 .
7 févr. 2009 à 13:16
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 ?
6 févr. 2009 à 23:37
<?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.