Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Зачем нужна битовая операция?
Форумы портала PHP.SU » » Вопросы новичков » Зачем нужна битовая операция?

Страниц (1): [1]
 

1. Rmydar - 13 Марта, 2017 - 17:22:26 - перейти к сообщению
Всем доброго времени суток! Не давно стал изучать PHP, и по большому счету пытаюсь понять чужой код. Так вот, есть такой метод для проверки IPv6 адресов.
PHP:
скопировать код в буфер обмена
  1.  
  2. public static function checkIp6($requestIp, $ip)
  3. {
  4.     if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) {
  5.         throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
  6.     }
  7.  
  8.     if (false !== strpos($ip, '/')) {
  9.         list($address, $netmask) = explode('/', $ip, 2);
  10.  
  11.         if ($netmask < 1 || $netmask > 128) {
  12.             return false;
  13.         }
  14.     } else {
  15.         $address = $ip;
  16.         $netmask = 128;
  17.     }
  18.  
  19.     $bytesAddr = unpack('n*', @inet_pton($address));
  20.     $bytesTest = unpack('n*', @inet_pton($requestIp));
  21.  
  22.     if (!$bytesAddr || !$bytesTest) {
  23.         return false;
  24.     }
  25.  
  26.     for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
  27.         $left = $netmask - 16 * ($i - 1);
  28.         $left = ($left <= 16) ? $left : 16;
  29.         $mask = ~(0xffff >> $left) & 0xffff;
  30.         if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
  31.             return false;
  32.         }
  33.     }    
  34.  
  35.     return true;
  36. }
  37.  

Принимает два параметра, IP адрес запроса, и IP адрес из массива доверенных узлов. Вопрос вызывает следующая строка кода.
PHP:
скопировать код в буфер обмена
  1.  
  2. $mask = ~(0xffff >> $left) & 0xffff;
  3.  

Зачем нужна эта битовая операция, если при любой длине префикса я получу одно и тоже значение? Почему нельзя его сразу назначить переменной mask? Буду признателен если сможете мне объяснить, а то мне кажется что я все время что-то упускаю.
2. OrmaJever - 13 Марта, 2017 - 19:28:30 - перейти к сообщению
при $left < 16 вы будете получать разные значение. Зачем это нужно в данном алгоритме не знаю, т.к. даже особо не всматривался
3. Rmydar - 13 Марта, 2017 - 20:07:50 - перейти к сообщению
OrmaJever пишет:
при $left < 16 вы будете получать разные значение. Зачем это нужно в данном алгоритме не знаю, т.к. даже особо не всматривался

Так то понятно что разные, а вот зачем в примере сделано так, непонятно. Я почему то долек от мысли что это сделано чисто для эстетики, что бы дать понять, что в маске содержится 16 единичек. Думаю здесь есть некий тайный смысл, тока вот в чем его суть непонятно)
(Добавление)
Ой прошу у всех прощение, надо же было так с глупить, с мной такое бывает, и это очень печально. Моя ошибка, я то думал что у меня left не может быть меньше 16, а там на оборот, если left меньше или равен 16 то left, если больше то 16, а значит не всегда 16 единичек). OrmaJever спасибо тебе большое, выел из ступора, вот написал тебе про 16 единичек, а потом подумал, а всегда ли их 16? А не деле не всегда, маски разные.

 

Powered by ExBB FM 1.0 RC1