Создание с файла массива с двумя переменными

Статус
В этой теме нельзя размещать новые ответы.

Levitt

Профессор
Регистрация
20 Май 2008
Сообщения
361
Реакции
43
Приветсвую, есть у меня огромный список IP организаций для блокировки. в формате
192.27.09.01-192.27.09.24
172.27.09.01-172.27.09.24
....
Сгуглил функцию по конвертации ИП -> CIDR, проблема только в том что не выходит задать для этого скрита массив списоком ип для обработки и отдачи результата.
PHP:
function PlageVersCIDRs($ip_min, $ip_max) {
$cidrs = array();
$ip_min_bin = sprintf('%032b', $ip_min);
$ip_max_bin = sprintf('%032b', $ip_max);
$ip_cour_bin = $ip_min_bin;
while (strcmp($ip_cour_bin, $ip_max_bin) <= 0) {
$lng_reseau = 32;
$ip_reseau_bin = $ip_cour_bin;
while (($ip_cour_bin[$lng_reseau - 1] == '0') && (strcmp(substr_replace($ip_reseau_bin, '1', $lng_reseau - 1, 1), $ip_max_bin) <= 0)) {
$ip_reseau_bin[$lng_reseau - 1] = '1';
$lng_reseau--;
}
$cidrs[] = long2ip(bindec($ip_cour_bin)).'/'.$lng_reseau;
$ip_cour_bin = sprintf('%032b', bindec($ip_reseau_bin) + 1);
}
return $cidrs;
}
 
Если $ip_min, $ip_max будут массивами, тогда так:
Код:
function PlageVersCIDRs($ip_min, $ip_max) 
{
$cidrs = array();
for(i=0;i<count($ip_min);i++)
{
   $ip_min_bin = sprintf('%032b', $ip_min[i]);
   $ip_max_bin = sprintf('%032b', $ip_max[i]);
   $ip_cour_bin = $ip_min_bin;
   while (strcmp($ip_cour_bin, $ip_max_bin) <= 0) 
   {
      $lng_reseau = 32;
      $ip_reseau_bin = $ip_cour_bin;
      while (($ip_cour_bin[$lng_reseau - 1] == '0') &&
       (strcmp(substr_replace($ip_reseau_bin, '1', $lng_reseau - 1, 1), 
       $ip_max_bin) <= 0)) 
      {
         $ip_reseau_bin[$lng_reseau - 1] = '1';
         $lng_reseau--;
      }
      $cidrs[] = long2ip(bindec($ip_cour_bin)).'/'.$lng_reseau;
      $ip_cour_bin = sprintf('%032b', bindec($ip_reseau_bin) + 1);
   }
}
return $cidrs;
}
 
Я так понял что строку нужно разделить на две переменные?


Попробуй функцией explode разделить ее вот так

PHP:
$arr=explode("-", $string);

и твои элементы $ip_min и $ip_max будут соответственно
PHP:
$ip_min=$arr[0];
$ip_max=$arr[1];

Их и передаешь в функцию свою
 
Спасибо за ответы, загвоздка как-раз в том как передать данные из файла в функцию.
PHP:
<?
$string = file_get_contents('list.txt');
$array=explode("-", $string); 
$ip_min_bin=$array[0]; 
$ip_max_bin=$array[1]; 
//////
function PlageVersCIDRs($ip_min, $ip_max) { 
$cidrs = array(); 
$ip_min_bin = sprintf('%032b', $ip_min); 
$ip_max_bin = sprintf('%032b', $ip_max); 
$ip_cour_bin = $ip_min_bin; 
while (strcmp($ip_cour_bin, $ip_max_bin) <= 0) { 
$lng_reseau = 32; 
$ip_reseau_bin = $ip_cour_bin; 
while (($ip_cour_bin[$lng_reseau - 1] == '0') && (strcmp(substr_replace($ip_reseau_bin, '1', $lng_reseau - 1, 1), $ip_max_bin) <= 0)) { 
$ip_reseau_bin[$lng_reseau - 1] = '1'; 
$lng_reseau--; 
} 
$cidrs[] = long2ip(bindec($ip_cour_bin)).'/'.$lng_reseau; 
$ip_cour_bin = sprintf('%032b', bindec($ip_reseau_bin) + 1); 
} 
return $cidrs; 
} 
?>
 
Код:
$string = file('list.txt');
for($i=0;$i<count($string);$i++)
{ 
   $array=explode("-", $string[i]);
   $ip_min[$i]=$array[0]; 
   $ip_max[$i]=$array[1];
}
PlageVersCIDRs($ip_min, $ip_max);
где
PlageVersCIDRs($ip_min, $ip_max)
описана мною ранее
 
Код:
PlageVersCIDRs($ip_min, $ip_max) 
описана мною ранее[/QUOTE]

Да, заметил, сначала не использвоал так как не увидел ошибку с заданим перенных в цикле.

Сделал по примеру, пока получаю в резулате Array ( [0] => 0.0.0.0/32 [1] => 0.0.0.0/32 )

[PHP]<?
$string = file('list.txt');
for($i=0;$i<count($string);$i++)
{ 
   $arr=explode("-", $string[i]);
   $ip_min[$i]=$arr[0]; 
   $ip_max[$i]=$arr[1];
print_r( $ip_min[$i] );
}

////////////////////
function PlageVersCIDRs($ip_min, $ip_max) 
{
$cidrs = array();
for($i=0;$i<count($ip_min);$i++)
{
   $ip_min_bin = sprintf('%032b', $ip_min[$i]);
   $ip_max_bin = sprintf('%032b', $ip_max[$i]);
   $ip_cour_bin = $ip_min_bin;
   while (strcmp($ip_cour_bin, $ip_max_bin) <= 0) 
   {
      $lng_reseau = 32;
      $ip_reseau_bin = $ip_cour_bin;
      while (($ip_cour_bin[$lng_reseau - 1] == '0') &&
       (strcmp(substr_replace($ip_reseau_bin, '1', $lng_reseau - 1, 1), 
       $ip_max_bin) <= 0)) 
      {
         $ip_reseau_bin[$lng_reseau - 1] = '1';
         $lng_reseau--;
      }
      $cidrs[] = long2ip(bindec($ip_cour_bin)).'/'.$lng_reseau;
      $ip_cour_bin = sprintf('%032b', bindec($ip_reseau_bin) + 1);
   }
}
return $cidrs;
}

////////////////////////
print_r( PlageVersCIDRs($ip_min, $ip_max) );

?>[/PHP]
 
Прошу прощения, еще одна ошибка:
$arr=explode("-", $string[$i]);
;)От синтаксиса С++ отвыкать трудно.
 
Что-то Ваша ф-ия у меня не хочет работать.
Во-первых, приведите ip к правильному виду:
192.27.09.01 -> 192.27.9.1
вот Вам полностью рабочий вариант (для PHP5)
PHP:
<?php
$content = file('list.txt');
$result = array();
foreach ($content as $string) {
    $string = trim($string);
    $array = explode("-", $string);
    $ip_min = $array[0];
    $ip_max = $array[1];
    $result[] = CIDR::rangeToCIDRList($ip_min, $ip_max);
}
echo "<pre>";
print_r($result);
echo "</pre>";
/**
 * CIDR.php
 *
 * Utility Functions for IPv4 ip addresses.
 *
 * @author Jonavon Wilcox <jowilcox@vt.edu>
 * @version Sat Jun  6 21:26:48 EDT 2009
 * @copyright Copyright (c) 2009 Jonavon Wilcox
 */
 /**
  * class CIDR.
  * Holds static functions for ip address manipulation.
  */
class CIDR {
    /**
     * method CIDRtoMask
     * Return a netmask string if given an integer between 0 and 32. I am 
     * not sure how this works on 64 bit machines.
     * Usage:
     *     CIDR::CIDRtoMask(22);
     * Result:
     *     string(13) "255.255.252.0"
     * @param $int int Between 0 and 32.
     * @access public
     * @static
     * @return String Netmask ip address
     */
    public static function CIDRtoMask($int) {
        return long2ip(-1 << (32 - (int)$int));
    }
    /**
     * method countSetBits.
     * Return the number of bits that are set in an integer.
     * Usage:
     *     CIDR::countSetBits(ip2long('255.255.252.0'));
     * Result:
     *     int(22)
     * @param $int int a number
     * @access public
     * @static
     * @see http://stackoverflow.com/questions/109023/best-algorithm-to-co\
     * unt-the-number-of-set-bits-in-a-32-bit-integer
     * @return int number of bits set.
     */
    public static function countSetbits($int){
        $int = $int - (($int >> 1) & 0x55555555);
        $int = ($int & 0x33333333) + (($int >> 2) & 0x33333333);
        return (($int + ($int >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
    }
    /**
     * method validNetMask.
     * Determine if a string is a valid netmask.
     * Usage:
     *     CIDR::validNetMask('255.255.252.0');
     *     CIDR::validNetMask('127.0.0.1');
     * Result:
     *     bool(true)
     *     bool(false)
     * @param $netmask String a 1pv4 formatted ip address.
     * @see http://www.actionsnip.com/snippets/tomo_atlacatl/calculate-if-\
     * a-netmask-is-valid--as2-
     * @access public
     * @static
     * return bool True if a valid netmask.
     */
    public static function validNetMask($netmask){
        $netmask = ip2long($netmask);
        $neg = ((~(int)$netmask) & 0xFFFFFFFF);
        return (($neg + 1) & $neg) === 0;
    }
    /**
     * method maskToCIDR.
     * Return a CIDR block number when given a valid netmask.
     * Usage:
     *     CIDR::maskToCIDR('255.255.252.0');
     * Result:
     *     int(22)
     * @param $netmask String a 1pv4 formatted ip address.
     * @access public
     * @static
     * @return int CIDR number.
     */
    public static function maskToCIDR($netmask){
        if(self::validNetMask($netmask)){
            return self::countSetBits(ip2long($netmask));
        }
        else {
            throw new Exception('Invalid Netmask');
        }
    }
    /**
     * method alignedCIDR.
     * It takes an ip address and a netmask and returns a valid CIDR
     * block.
     * Usage:
     *     CIDR::alignedCIDR('127.0.0.1','255.255.252.0');
     * Result:
     *     string(12) "127.0.0.0/22"
     * @param $ipinput String a IPv4 formatted ip address.
     * @param $netmask String a 1pv4 formatted ip address.
     * @access public
     * @static
     * @return String CIDR block.
     */
    public static function alignedCIDR($ipinput,$netmask){
        $alignedIP = long2ip((ip2long($ipinput)) & (ip2long($netmask)));
        return "$alignedIP/" . self::maskToCIDR($netmask);
    }
    /**
     * method IPisWithinCIDR.
     * Check wether an IP is within a CIDR block.
     * Usage:
     *     CIDR::IPisWithinCIDR('127.0.0.33','127.0.0.1/24');
     *     CIDR::IPisWithinCIDR('127.0.0.33','127.0.0.1/27');
     * Result: 
     *     bool(true)
     *     bool(false)
     * @param $ipinput String a IPv4 formatted ip address.
     * @param $cidr String a IPv4 formatted CIDR block. Block is aligned
     * during execution.
     * @access public
     * @static
     * @return String CIDR block.
     */
    public static function IPisWithinCIDR($ipinput,$cidr){
        $cidr = explode('/',$cidr);
        $cidr = self::alignedCIDR($cidr[0],self::CIDRtoMask((int)$cidr[1]));
        $cidr = explode('/',$cidr);
        $ipinput = (ip2long($ipinput));
        $ip1 = (ip2long($cidr[0]));
        $ip2 = ($ip1 + pow(2, (32 - (int)$cidr[1])) - 1);
        return (($ip1 <= $ipinput) && ($ipinput <= $ip2));
    }
    /**
     * method maxBlock.
     * Determines the largest CIDR block that an IP address will fit into.
     * Used to develop a list of CIDR blocks.
     * Usage:
     *     CIDR::maxBlock("127.0.0.1");
     *     CIDR::maxBlock("127.0.0.0");
     * Result:
     *     int(32)
     *     int(8)
     * @param $ipinput String a IPv4 formatted ip address.
     * @access public
     * @static
     * @return int CIDR number.
     */
    public static function maxBlock($ipinput) {
        return self::maskToCIDR(long2ip(-(ip2long($ipinput) & -(ip2long($ipinput)))));
    }
    /**
     * method rangeToCIDRList.
     * Returns an array of CIDR blocks that fit into a specified range of
     * ip addresses.
     * Usage:
     *     CIDR::rangeToCIDRList("127.0.0.1","127.0.0.34");
     * Result:
     *     array(7) { 
     *       [0]=> string(12) "127.0.0.1/32"
     *       [1]=> string(12) "127.0.0.2/31"
     *       [2]=> string(12) "127.0.0.4/30"
     *       [3]=> string(12) "127.0.0.8/29"
     *       [4]=> string(13) "127.0.0.16/28"
     *       [5]=> string(13) "127.0.0.32/31"
     *       [6]=> string(13) "127.0.0.34/32"
     *     }
     * @param $startIPinput String a IPv4 formatted ip address.
     * @param $startIPinput String a IPv4 formatted ip address.
     * @see http://null.pp.ru/src/php/Netmask.phps
     * @return Array CIDR blocks in a numbered array.
     */
    public static function rangeToCIDRList($startIPinput,$endIPinput) {
        $start = ip2long($startIPinput);
        $end = ip2long($endIPinput);
        while($end >= $start) {
            $maxsize = self::maxBlock(long2ip($start));
            $maxdiff = 32 - intval(log($end - $start + 1)/log(2));
            $size = ($maxsize > $maxdiff)?$maxsize:$maxdiff;
            $listCIDRs[] = long2ip($start) . "/$size";
            $start += pow(2, (32 - $size));
        }
        return $listCIDRs;
    }
}
?>
если list.txt содержит
Код:
192.27.9.1-192.27.9.24                                                                                                                                       
172.27.9.1-172.27.9.24
получаем
Код:
Array
(
    [0] => Array
        (
            [0] => 192.27.9.1/32
            [1] => 192.27.9.2/31
            [2] => 192.27.9.4/30
            [3] => 192.27.9.8/29
            [4] => 192.27.9.16/29
            [5] => 192.27.9.24/32
        )
    [1] => Array
        (
            [0] => 172.27.9.1/32
            [1] => 172.27.9.2/31
            [2] => 172.27.9.4/30
            [3] => 172.27.9.8/29
            [4] => 172.27.9.16/29
            [5] => 172.27.9.24/32
        )
)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху