За последние 24 часа нас посетили 15947 программистов и 1637 роботов. Сейчас ищут 892 программиста ...

Проверка IP на вхождение в диапазон.

Тема в разделе "PHP для новичков", создана пользователем Dicerona, 20 ноя 2008.

  1. Dicerona

    Dicerona Активный пользователь

    С нами с:
    19 ноя 2008
    Сообщения:
    2
    Симпатии:
    0
    Всем привет.
    У меня такая вот проблема: есть найденный в сети скрипт, который проверяет айпишник пользователя, пришедшего на сайт, на принадлежность к диапазону. В тестовом виде все работает отлично:

    PHP:
    1. <?php
    2.  
    3. function CheckIP ( )
    4. {
    5. $ip_arr = explode ( '/' , '212.98.160.0/19' );
    6. $network_long = ip2long ( $ip_arr [ 0 ]);
    7.  
    8. $x = ip2long ( $ip_arr [ 1 ]);
    9. $mask = long2ip ( $x ) == $ip_arr [ 1 ] ? $x : 0xffffffff << ( 32 - $ip_arr [ 1 ]);
    10. $ip_long = ip2long ( $_SERVER['REMOTE_ADDR'] );
    11.  
    12.   // echo ">".$ip_arr[1]."> ".decbin($mask)."\n";
    13. return ( $ip_long & $mask ) == ( $network_long & $mask );
    14. }
    15.  
    16. ?>
    Айпишник моего компа входит в диапазон и то что нужно отображается, а когда захожу через проксю - нет. Что и требуется.

    Но нужно прикрутить проверку многих диапазонов, по-этому я "написал" вот это:

    PHP:
    1. <?php
    2.  
    3. function CheckIP()
    4. {
    5.        
    6.     $range_from = array("62.32.47.0/24", "62.32.61.0/28", "62.187.241.0/27", "65.110.43.30/31", "65.110.43.32/29", "65.110.45.150/31", "65.110.45.152/29", "65.110.50.40/29", "65.110.50.48/31", "65.110.54.20/30", "65.110.54.24/30", "65.110.54.28/31", "66.118.187.128/29", "66.118.187.152/29", "77.74.32.0/21", "78.109.30.32/29", "79.98.48.0/21", "79.170.104.0/21", "80.94.160.0/20", "80.94.224.0/20", "80.249.80.0/20", "81.25.32.0/20", "81.30.80.0/20", "82.209.192.0/18", "84.201.224.0/20", "86.57.128.0/17", "87.252.224.0/19",  "91.149.128.0/18", "91.187.0.0/19", "93.84.0.0/15", "93.125.0.0/17", "93.191.96.0/21", "193.17.173.0/24", "193.26.18.0/24", "193.151.40.0/22", "193.232.92.0/24", "193.232.248.0/22", "194.67.192.0/23", "194.69.70.72/29", "194.84.74.64/26", "194.84.74.128/25", "194.84.145.0/24", "194.85.254.0/23", "194.158.192.0/19", "194.226.120.0/22", "194.226.124.0/23", "194.226.126.0/24", "195.50.0.0/19", "195.51.243.0/26",  "195.95.218.0/23", "195.137.160.0/24", "195.137.180.0/24", "195.212.202.64/26", "195.222.64.0/19", "206.49.97.0/24", "207.150.184.120/29", "207.241.164.224/28", "208.66.193.80/28", "212.63.175.174/32",  "212.95.54.0/24", "212.98.160.0/19", "212.176.22.32/27", "212.176.22.64/26", "212.176.22.128/27", "212.176.22.192/26", "213.85.57.0/24", "213.156.141.0/24", "213.184.224.0/19", "217.21.32.0/19", "217.23.112.0/20", "217.107.213.0/25");
    7.    
    8.     $ip_long = ip2long ( $_SERVER['REMOTE_ADDR'] );
    9.     for ($i = 0; $i < 72; $i++)
    10.     {
    11.    
    12.         $ip_arr = explode ( '/' , $range_from[i] );
    13.         $network_long = ip2long ( $ip_arr[0] );
    14.  
    15.         $x = ip2long ( $ip_arr [1]);
    16.         $mask = long2ip ( $x ) == $ip_arr [ 1 ] ? $x : 0xffffffff << ( 32 - $ip_arr [ 1 ]);
    17.        
    18.         // echo ">".$ip_arr[1]."> ".decbin($mask)."\n";
    19.          if(( $ip_long & $mask ) == ( $network_long & $mask )) return true;
    20.        
    21.     }
    22.  
    23.    
    24.     return false;
    25. }
    26.  
    27. ?>
    И вот эта дрянь уже работать не захотела, помогите пожалуйста, где я намуд(р)ил?

    P.S. :
    Сразу массив range_from инициализировался константами- не работало, поменял на строке - один хрен. Переменными тут вроде не отделаешься. На мой дилетантский взгляд синтаксис правильный, тем более что большей частью код скопипастен. Увы я PHP пока не знаю.
     
  2. Mete0

    Mete0 Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    272
    Симпатии:
    0
    Адрес:
    Gatchina

    Вижу опечатку:
    $ip_arr = explode ( '/' , $range_from[i] );
    Надо:
    $ip_arr = explode ( '/' , $range_from[$i] );
     
  3. Mete0

    Mete0 Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    272
    Симпатии:
    0
    Адрес:
    Gatchina
    А ещё лучше так:
    for ($i = 0; $i < $size = count($range_from); $i++)
     
  4. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
    так же при каждой интеграции будет размер массива вычислятся..
     
  5. Mete0

    Mete0 Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    272
    Симпатии:
    0
    Адрес:
    Gatchina
    Sephiroth_Lukaw
    Нет, он один раз высчитает, обрати внимание на:
    На $size = count($range_from)

    http://ru2.php.net/for Последний пример:
     
  6. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
    Спасибо, точно.
     
  7. Adamant

    Adamant Активный пользователь

    С нами с:
    8 апр 2007
    Сообщения:
    234
    Симпатии:
    0
    Адрес:
    Казахстан г.Тараз
    Позволю с вами не согласиться:
    Замечу, что
    for($i = 0, $size = sizeof($people); $i < $size; ++$i)
    и
    for ($i = 0; $i < $size = count($range_from); $i++)
    все же разные вещи, в первом случае при инициализации будет 1 раз вычислен размер массива и значение присвоено переменной $size. (Как в приведенном вами примере с http://ru2.php.net/for)
    А во втором случае (в вашем) при каждой итерации будет вычисляться размер массива и значение присваиваться переменной $size.

    Чтобы не быть голословным.
    Пример с http://ru2.php.net/for:
    PHP:
    1. // создал ("накопипастил") большой вложенный массив элементов на 1000
    2. $array = array(..............................................
    3.                        ..............................................
    4.                        ..............................................
    5.                       );
    6. // отсечка времени
    7. $time = microtime(true);
    8.  
    9. for ($i = 0, $count = count($array); $i < $count; $i++) {
    10.     $test[$i] = 1;
    11. }
    12.  
    13. printf("Время работы скрипта: %f c<br />", microtime(true) - $time); // в среднем получилось чуть меньше 0.000500 c
    А в вашем случае:
    PHP:
    1. for ($i = 0; $i < count($array); $i++) {
    2.     $test[$i] = 1;
    3. }
    4.  
    5. printf("Время работы скрипта: %f c<br />", microtime(true) - $time); // в среднем получилось около 0.000900 c
    Разница 0.000500 c и 0.000900 c заметная.

    А вы пишете "Нет, он один раз высчитает". Вводите в заблуждение людей!
    [​IMG]
     
  8. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    А главное, был бы прок оптимизировать. count() - это очень быстрая нативная функция, немногим медленнее чтения значения из переменной ;)
    Если внутри цикла будет что-то чуть посложнее одного присваивания, вся ваша копеечная экономия прикажет долго жить.
     
  9. Adamant

    Adamant Активный пользователь

    С нами с:
    8 апр 2007
    Сообщения:
    234
    Симпатии:
    0
    Адрес:
    Казахстан г.Тараз
    Полностью согласен. Но я не удержался и написал, потому что было категоричное высказывание "что при каждой итерации не будет вычисляться значение, а лишь при инициализации цикла". А на счет экономии даже где-то в мануале(книге) читал такое и кстати так же если нет строгой необходимости пишу
    for($i; $i< sizeof($array); $i++) - потому как более визуально приятнее.
    [​IMG]
     
  10. ser_ega

    ser_ega Активный пользователь

    С нами с:
    13 ноя 2008
    Сообщения:
    56
    Симпатии:
    0
    Ребят а как узнать IP адрес локального компьютера?
     
  11. Adamant

    Adamant Активный пользователь

    С нами с:
    8 апр 2007
    Сообщения:
    234
    Симпатии:
    0
    Адрес:
    Казахстан г.Тараз
  12. Mete0

    Mete0 Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    272
    Симпатии:
    0
    Адрес:
    Gatchina
    В моем случае как раз таки и не так, а
    Видишь разницу? :)

    А теперь проверим:
    PHP:
    1. #!/usr/local/bin/php
    2. <?php
    3. $array= array("62.32.47.0/24", "62.32.61.0/28", "62.187.241.0/27", "65.110.43.30/31", "65.110.43.32/29", "65.110.45.150/31", "65.110.45.152/29", "65.110.50.40/29", "65.110.50.48/31", "65.110.54.20/30", "65.110.54.24/30", "65.110.54.28/31", "66.118.187.128/29", "66.118.187.152/29", "77.74.32.0/21", "78.109.30.32/29", "79.98.48.0/21", "79.170.104.0/21", "80.94.160.0/20", "80.94.224.0/20", "80.249.80.0/20", "81.25.32.0/20", "81.30.80.0/20", "82.209.192.0/18", "84.201.224.0/20", "86.57.128.0/17", "87.252.224.0/19",  "91.149.128.0/18", "91.187.0.0/19", "93.84.0.0/15", "93.125.0.0/17", "93.191.96.0/21", "193.17.173.0/24", "193.26.18.0/24", "193.151.40.0/22", "193.232.92.0/24", "193.232.248.0/22", "194.67.192.0/23", "194.69.70.72/29", "194.84.74.64/26", "194.84.74.128/25", "194.84.145.0/24", "194.85.254.0/23", "194.158.192.0/19", "194.226.120.0/22", "194.226.124.0/23", "194.226.126.0/24", "195.50.0.0/19", "195.51.243.0/26",  "195.95.218.0/23", "195.137.160.0/24", "195.137.180.0/24", "195.212.202.64/26", "195.222.64.0/19", "206.49.97.0/24", "207.150.184.120/29", "207.241.164.224/28", "208.66.193.80/28", "212.63.175.174/32",  "212.95.54.0/24", "212.98.160.0/19", "212.176.22.32/27", "212.176.22.64/26", "212.176.22.128/27", "212.176.22.192/26", "213.85.57.0/24", "213.156.141.0/24", "213.184.224.0/19", "217.21.32.0/19", "217.23.112.0/20", "217.107.213.0/25");
    4. $time = microtime(true);
    5. for ($i = 0; $i < count($array); $i++)
    6.   $test[$i] = 1;
    7. printf("Время работы скрипта: %f c\n", microtime(true) - $time);
    8. $time = microtime(true);
    9. for ($i = 0; $i < $size = count($array); $i++)
    10.   $test[$i] = 1;
    11. printf("Время работы скрипта: %f c\n", microtime(true) - $time);
    12. ?>
    Как раз таки один раз и выщитывается, так что в заблуждение людей вводишь ты.
     
  13. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Вы меня заставили отвлечься от черчения курсача по водоснабжению :E
    PHP:
    1.  
    2. <?php
    3. $array = Array(1, 2, 3, 4, 5, 6, 7);
    4. function gg($array) {
    5.     echo 'ohh no!<br>';
    6.     return sizeof($array);
    7. }
    8. for ($i = 0; $i < $count = gg($array); $i++);
    9. ?>
    10.  
    result:
    Код (Text):
    1.  
    2. ohh no!
    3. ohh no!
    4. ohh no!
    5. ohh no!
    6. ohh no!
    7. ohh no!
    8. ohh no!
    9. ohh no!



    PHP:
    1. <?php
    2. $array = Array(1, 2, 3, 4, 5, 6, 7);
    3. function gg($array) {
    4.     echo 'ohh no!<br>';
    5.     return sizeof($array);
    6. }
    7. for ($i = 0; $i < gg($array); $i++);
    8. ?>
    Код (Text):
    1.  
    2. ohh no!
    3. ohh no!
    4. ohh no!
    5. ohh no!
    6. ohh no!
    7. ohh no!
    8. ohh no!
    9. ohh no!


    PHP:
    1. <?php
    2. $array = Array(1, 2, 3, 4, 5, 6, 7);
    3. function gg($array) {
    4.     echo 'ohh no!<br>';
    5.     return sizeof($array);
    6. }
    7. for ($i = 0, $count = gg($array); $i < $count; $i++);
    8. ?>
    Код (Text):
    1.  
    2. ohh no!

    P.S. В for только первый параметр выполняется один раз, а остальные - при каждой итерации.
     
  14. Mete0

    Mete0 Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    272
    Симпатии:
    0
    Адрес:
    Gatchina
    На самом деле я не прав, разница во времени выполнения этого примера приведённого мною выше совсем не из-за этого.
    Это можно легко проверить поменяв местами.
    PHP:
    1. for ($i = 0; $i < count($array); $i++);
    2. for ($i = 0; $i < $size = count($array); $i++);
    3.  
    При каждой итерации будет заново считаться count.
    Мне просто вначале показалось что php "оптимизирует" такое выражение. Но это не так, да и не должно быть так...
    В общем переклинело меня сегодня немного что-то. Извиняюсь за то что ввел кого-то в заблуждение..
     
  15. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Бывает, главное -- вовремя оклиматься, а не на смертный бой идти.
     
  16. Dicerona

    Dicerona Активный пользователь

    С нами с:
    19 ноя 2008
    Сообщения:
    2
    Симпатии:
    0
    Спасибо всем откликнувшимся, очень познавательно. Завтра (те уже сегодня, но попозже) сообщу результаты.
     
  17. ser_ega

    ser_ega Активный пользователь

    С нами с:
    13 ноя 2008
    Сообщения:
    56
    Симпатии:
    0
    Все это хорошо знакомо мне, но мне нужно узнать его программно в php...
    для того чтобы выдавать определенные права с привязкой по айпи, ну и возможно подсчета находящихся на сайте пользователей - кстати может такое уже есть готовое?
     
  18. Adamant

    Adamant Активный пользователь

    С нами с:
    8 апр 2007
    Сообщения:
    234
    Симпатии:
    0
    Адрес:
    Казахстан г.Тараз
    PHP:
    1. $_SERVER['REMOTE_ADDR'];
     
  19. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    По поводу microtime() вопросик ещё возник. В начале скрипта вставляю такое:
    $mcrtime = microtime();
    В конце такое:
    $mcrtime = microtime() - $mcrtime;
    echo $mcrtime;
    Обычно выскакивает вполне понятное 0.00хххх или 0.0ххххх, но иногда почему-то совсем непонятное -0.9ххххх . Почему?
     
  20. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    sobachnik
    Видимо твой скрипт работает назад во времени, не тормозя, а ускоряя сервер! Научи нас тоже :lol:
     
  21. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    :lol: :lol: :lol:
    Забавно! Только ведь он не всегда так работает... :) Обычно внизу появляется вполне понятное 0.00хххх, и где-то примерно в 5% случаях вот это -0.9ххххх . Причём в тексте самого скрипта не делаю никаких изменений - просто нажимаю F5 в браузере и примерно 1 раз на 20 выскакивает эта хрень... :roll:
     
  22. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
  23. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Sergey89, спасибо! :) Мучал свой бедный комп наверно минуты три нажимая обновить, отрицательных значений не выскакивает! :) И всё же интересно, почему так было...?
     
  24. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    сделай, а потом