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

Тема в разделе "PHP", создана пользователем Levitt, 17 мар 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    356
    Симпатии:
    34
    Приветсвую, есть у меня огромный список 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 11), $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;
    }
     
  2. zss

    zss Постоялец

    Регистр.:
    22 июн 2007
    Сообщения:
    55
    Симпатии:
    6
    Если $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;
    }  
    
     
  3. drawing4

    drawing4

    Регистр.:
    21 ноя 2008
    Сообщения:
    323
    Симпатии:
    37
    Я так понял что строку нужно разделить на две переменные?


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

    PHP:
    $arr=explode("-"$string);
    и твои элементы $ip_min и $ip_max будут соответственно
    PHP:
    $ip_min=$arr[0];
    $ip_max=$arr[1];
    Их и передаешь в функцию свою
     
  4. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    356
    Симпатии:
    34
    Спасибо за ответы, загвоздка как-раз в том как передать данные из файла в функцию.
    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 11), $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

    ?>
     
  5. zss

    zss Постоялец

    Регистр.:
    22 июн 2007
    Сообщения:
    55
    Симпатии:
    6
    Код:
    $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)
    описана мною ранее
     
  6. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    356
    Симпатии:
    34
     
  7. zss

    zss Постоялец

    Регистр.:
    22 июн 2007
    Сообщения:
    55
    Симпатии:
    6
    Прошу прощения, еще одна ошибка:
    $arr=explode("-", $string[$i]);
    ;)От синтаксиса С++ отвыкать трудно.
     
  8. bondaf

    bondaf Постоялец

    Регистр.:
    16 мар 2010
    Сообщения:
    85
    Симпатии:
    20
    Что-то Ваша ф-ия у меня не хочет работать.
    Во-первых, приведите 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(-<< (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
            )
    )
    
     
    Levitt нравится это.
Статус темы:
Закрыта.