почему мы сдвигаем биты при проверке IP-адреса - PullRequest
2 голосов
/ 21 июня 2010

У меня есть диапазон IP-адресов, и мне нужно проверить, попадает ли мой клиент, который обращается к моему приложению, в этот диапазон. Я пролистал несколько статей, и они разбили биты после разделения IP

, например, 127.0.0.1 разделяется после '. 'и после разбиения мы получаем массив из 4 элементов, каждый из которых сдвигается

element 1 >> 24;

и т. Д. .... и подвели итоги вместе, чтобы проверить.

Могу ли я знать, почему мы используем здесь оператор сдвига?

Ответы [ 4 ]

4 голосов
/ 21 июня 2010

Код, вероятно, должен быть примерно таким (я не запускал его, поэтому вам может потребоваться исправить небольшие проблемы, такие как небольшие ошибки компиляции или обработка переполнения):

uint GetIpValue(uint[] values)
{
  return (values[0] << 24) + 
         (values[1] << 16) + 
         (values[2] << 8) + 
         (values[3]);
}

Это создает uint значение, которое больше, если левая часть IP больше, как обычно определяется сравнение IP.

Теперь вы можете рассчитать каждое такое значение IP, чтобы увидеть, является ли оно ниже или больше другого значения IP.

Пример:

bool IsIpInRange(uint[] ip, uint[] ipStart, uint[] ipEnd)
{
  uint ipValue = GetIpValue(ip);
  return ipValue >= GetIpValue(ipStart) && ipValue <= GetIpValue(ipEnd);
}
1 голос
/ 21 июня 2010

Каждый октет IP-адреса составляет 8 бит, поэтому весь адрес составляет 32 бита и помещается в целое число. Я предполагаю, что они преобразуют строковое представление IP-адреса в целое число, вытаскивая четыре октета и сдвигая их по битам в четыре слова в целом

1 голос
/ 21 июня 2010

Я не совсем уверен, что вы имеете в виду, но я рискну предположить, что вы используете маску?

т.е. если вы хотите проверить, что ваш диапазон составляет 127.XXX.XXX.XXX тогда ваша маска будет равна / 8, что означает, что вы сохраняете только 8 бит из 32. Затем вам нужно сместить более 24 бит, чтобы вы могли посмотреть на 127.

127.0.0,1 = 0111 1111.0000 00000000 00000000 0001

127.0.0.1 и 255.0.0.0 = 0111 1111.0000 00000000 00000000 0000 = 127.0.0.0

127.0.0.1 и 255.0.0.0 >> 24 = 0111 1111 = 127

0 голосов
/ 21 июня 2010

Просто догадываюсь здесь, но кажется вполне логичным, что, поскольку адреса IPv4 умещаются в целое число (оба по 4 байта), проверка диапазона может выполняться с помощью обычных операторов < и >. Все, что вы делаете, это упаковываете свой IPv4-адрес в целое число (127.0.0.1 -> 0x7F000001) и проверяете, находится ли он в диапазоне двух ранее упакованных ребер интервала, как если бы вы просто проверяли, находится ли 5 ​​в 1 ... 10 интервал.

Также гораздо проще узнать, принадлежит ли ваш IP-адрес тому маскированному IP-адресу, с которым вы проверяете. Упакуйте его в целое число, сдвиньте их оба на количество битов, которые обнуляются в маске, и просто сравните их друг с другом с помощью простой операции равенства. (127.0.0.1/8 -> 0x7F000001 >> 8 -> 0x7F0000 == (0x7F000005 >> 8) <- 127.0.0.5) </p>

...