comparer 2 entiers non signés

comparer 2 entiers non signés - PHP - Programmation

Marsh Posté le 17-07-2006 à 13:37:51    

J'ai un petit souci.
Je voudrais déterminer si une adresse IP (string en x.x.x.x) appartient à un interval d'ip (aussi en string x.x.x.x). Pour cela, j'utilise ip2long pour convertir en un entier. Cet entier de retour est normalement non signé. Hors, PHP ne gère pas vraiment les ip non signés. Pour lui, un entier est toujours signé et donc si je fais ca : If (a < x && x < b) pour tester mon intervalle, ça ne fonctionne pas ! Car, par exemple, l'ip 3232237203, devient un nombre négatif, bref, ma condition foire.  
quelqu'un à une astuce SVP ?


Message édité par nORKy le 17-07-2006 à 13:38:26
Reply

Marsh Posté le 17-07-2006 à 13:37:51   

Reply

Marsh Posté le 17-07-2006 à 13:48:16    

pourquoi tu fais pas un strcmp sur tes deux chaines qui contiennent les ips plutôt?

Reply

Marsh Posté le 17-07-2006 à 13:54:46    

Mouai... Que risque t-il si je compare par exemple ww.xxx.y.zzz avec w.x.yyy.z ??
Si strcmp se voit comparer '.' et un chiffre, . sera toujours considéré comme inférieur à un nombre ('.' vaut 46 en décimal et les nombres commencent à 48) .. Ca risque de posé des problèmes dans certains cas ca.. non ?

Reply

Marsh Posté le 17-07-2006 à 13:57:29    

bin alors split tes chaines sur "." et compares tes tableaux case à case, en plus tu seras sur d'avoir des int dans celles-ci.

Reply

Marsh Posté le 17-07-2006 à 14:07:54    

oui, je ne n'ai que cette solution apparement.. dommage. Merci quand meme

Reply

Marsh Posté le 17-07-2006 à 19:56:45    

moi je serais toi, j'écrirais chaque nombre sur 3 chiffres poru avoir le même format
 
a.b.c.d devient 00a.00b.00c.00d
 
ensuite tu implodes chaques éléments sur le . et tu te retrouves avec 2 nombres entiers non signés comparables puiqu'il ont le même format.
 
Dis moi ce que tu en penses
 
++

Reply

Marsh Posté le 18-07-2006 à 09:28:06    

finalement, plutot que de rajouter des 0, j'ai fait des explodes, voici donc la fonction
elle est basé sur strcmp pour la valeur de retour, -1 quand ip1 < ip2, 1 quand ip1 > ip2 et 0 quand ce sont les memes :

Code :
  1. function ipcmp($ip1, $ip2)
  2. {
  3. $parts1 = explode(".", $ip1);
  4. $parts2 = explode(".", $ip2);
  5. for ($i = 0; $i < 4; $i++) {
  6.  if (intval($parts1[$i]) < intval($parts2[$i]))
  7.   return (-1);
  8.  if (intval($parts1[$i]) > intval($parts2[$i]))
  9.   return (1);
  10. }
  11. return (0);
  12. }

Reply

Marsh Posté le 18-07-2006 à 09:55:58    

mouais :/ tant qu'a faire j'aurais fait une fonction générique de comparaison de tableaux plutot qu'un cas spécial....
Un truc dans le genre:

Code :
  1. function array_cmp($t,$u){
  2.   if ( (count($t) == count($u)) !== true){
  3.     return 1 - 2*(count($t)<count($u));
  4.   }
  5.   for($i=0; $i<=count($t); $i++){
  6.     if ( $t[$i] !== $u[$i]){
  7.       return 1 - 2*($t[$i]<$u[$i]);
  8.     }
  9.   }
  10.   return 0;
  11. }


Et du coup pour ton besoin tu fesais:

Code :
  1. array_cmp(split(".",$ip1), split(".",$ip2));


Mais bon question de gout [:spamafote]

Reply

Marsh Posté le 18-07-2006 à 10:13:47    

Petit extrait de la doc officielle :  

Citation :

Note :  Comme les entiers PHP sont signés et que beaucoup d'adresses IP peuvent être des entiers négatifs, vous devez utiliser le formateur "%u" de la fonction sprintf() ou printf()  pour récupérer une représentation sous la forme d'une chaîne de caractères pour les adresses IP non signées.


 
bah après il suffit de "caster" (implicite en php  :sweat: ) le retour de printf pour faire les calculs.

Reply

Marsh Posté le 18-07-2006 à 12:02:37    

déjà, printf retourne la longueur de la chaine imprimé.
Ensuite, je pense que tu parle de sprintf qui lui retourne la chaine
Ensuite :
tu veux caster quoi ? tu veux caster une string en int ??!
Meme si ton cast est accepté et rélaiser, le problème est toujours le même puisque tu vas caster en int signé ;-)

Reply

Marsh Posté le 18-07-2006 à 12:02:37   

Reply

Marsh Posté le 18-07-2006 à 12:20:54    

oui sprintf,
mais quite à faire un peu grade autant utiliser le fait que php est faiblement typé.
grosso modo et à tester avec des float :

Code :
  1. $ip1 = floatval(sprintf("%u", ip2long($str_ip1)));
  2. $ip2 =  floatvalsprintf("%u", ip2long($str_ip2)));
  3. if($ip1 > $ip2)
  4. {
  5. etc...
  6. }


 
Le float est normalement plus grand que int ...
ou sinon (toujours à tester)

Code :
  1. $ip = (float)  ip2long($str_ip1);


Message édité par Monsieur Seb le 18-07-2006 à 12:25:34
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed