francoisch Posté 29 Décembre 2013 Posté 29 Décembre 2013 (modifié) BonjourJ’ai un tableau PHP avec des plages d’adresses IP et leur CIDR, par exemple : "….,"78.153.224.0/19","78.155.128.0/19","78.159.0.0/19","78.192.0.0/10","…….. Je souhaite vérifier qu’une adresse Ip, par exemple 78.229.96.137, fait, ou non, partie du tableau.Naturellement, la difficulté est dans l’interprétation des CIDR pour faire cette validation.Merci par avance de vos suggestions.Francois Modifié 29 Décembre 2013 par Dan Merci d'éviter de changer la police, surtout pour nous affubler de "comic sans"... Voir les règles du Hub concernant les enrichissements typographiques !!!
francoisch Posté 29 Décembre 2013 Auteur Posté 29 Décembre 2013 Je prie le modérateur de m'excuser de ce manquement aux règles, convenant simplement que je ne la connaissais pas. Il n'y avait aucune malice ou recherche de fantaisie dans ma démarche. Francois
Dan Posté 3 Janvier 2014 Posté 3 Janvier 2014 Ceci devrait donner le résultat que tu cherches /** * Check an IP adress against a CIDR * * @param string $cidr * @param string $ip * @return boolean */ function _cidrMatch($cidr, $ip) { // Get the base and the bits from the CIDR list($base, $bits) = explode('/', $cidr); // Now split it up into it's classes list($a, $b, $c, $d) = explode('.', $base); // Now do some bit shifting/switching to convert to ints $i = ($a << 24) + ($b << 16) + ($c << 8) + $d; $mask = $bits == 0 ? 0: (~0 << (32 - $bits)); // Here's our lowest int $low = $i & $mask; // Here's our highest int $high = $i | (~$mask & 0xFFFFFFFF); // Now split the ip we're checking against up into classes list($a, $b, $c, $d) = explode('.', $ip); // Now convert the ip we're checking against to an int $check = ($a << 24) + ($b << 16) + ($c << 8) + $d; // If the ip is within the range, including highest/lowest values, // then it's witin the CIDR range if ($check >= $low && $check <= $high) { return true; } else { return false; } }
francoisch Posté 3 Janvier 2014 Auteur Posté 3 Janvier 2014 bonjour Dan et merci pour ta réponse. J'avais bien compris que le sujet n'était pas simple mais, à voir ta réponse, j'en ai bien la confirmation. Je vais copier ton code, le comprendre et le tester, un chouette travail en perspective. Merci encore à toi. Francois
francoisch Posté 30 Janvier 2014 Auteur Posté 30 Janvier 2014 (modifié) bonjour Dan, Je reprend ton code après une interruption imprévue. Ma question: sous quel format exact doit être présenté l'argument $cidr ? J'obtient facilement un bloc de CIDR sous ce format: 5.10.78.240/29 5.10.83.0/25 5.10.85.212/30 27.116.56.0/22 ... dans un fichier plat. Faut-il que je le transforme en string comme "5.10.78.240/29", "5.10.83.0/25", "5.10.85.212/30", "27.116.56.0/22", ... ? Si Oui, avec un Fread du fichier plat et un Fwrite dans un fichier Php? Merci par avance de ton aide. Francois Modifié 31 Janvier 2014 par francoisch
francoisch Posté 31 Janvier 2014 Auteur Posté 31 Janvier 2014 bonjour J’ai pris les CDIP de la France et mon adresse IP (Paris) ; le résultat de la recherche devrait être TRUE. Le début de ma liste de CDIP : "2.0.0.0/12 ","5.10.82.128/29 ","5.10.94.240/29 ","5.10.128.0/21 ","….aménagée dans un fichier nommé france.php. Je lis ce fichier avec ce bout de code qui utilise la fonction indiquée plus haut : $fichierEntree = "france.php";$adresseIp = "1.2.3.4"; (adresse réelle changée pour ce post)$retour = _cidrMatch($fichierEntree, $adresseIp); echo " retour".$retour."<br>";if ( $retour == FALSE ) { echo "Retour = False"; }else { echo "Retour = True"; }mais la variable $retour est vide. Merci de vos conseils. Francois
Dan Posté 1 Février 2014 Posté 1 Février 2014 Où as-tu vu que le premier argument de la fonction _cidrMatch() devait être un fichier Remplace-le par une adresse IP avec cidr, comme "1.2.3.4/24" et refais un test ! Il te faut lire le fichier en boucle et appeler la fonction pour chaque IP/CIDR !
Dan Posté 1 Février 2014 Posté 1 Février 2014 Avec un fichier IPS.txt qui contient ceci : 27.116.56.0/22 5.10.78.240/29 5.10.83.0/25 5.10.85.212/30 Ce code fonctionne bien et sort de la boucle dès qu'un match est trouvé : $monip="5.10.83.12"; $fp=fopen("IPS.txt", "r"); while(($ip = fgets($fp)) !== false) { if(_cidrMatch($ip, $monip)) { echo "found in : $ip "; break; } } ou, comme alternative, avec valeur de sortie "0" si l'IP est non trouvée, "1" si l'IP est trouvée. : $monip="5.10.83.12"; $fp=fopen("IPS.txt", "r"); while(($ip = fgets($fp)) !== false) { if(_cidrMatch($ip, $monip)) exit(1); } exit(0); Ce n'était pourtant pas compliqué, si ?
francoisch Posté 1 Février 2014 Auteur Posté 1 Février 2014 bonjour Dan J'ai repris ton code et, effectivement, ça fonctionne impeccablement. Je n'y étais pas arrivé seul. Merci de ton aide précieuse. Francois
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant