Я пытаюсь придумать эффективную структуру данных для представления диапазонов IP-адресов, как описано чуть ниже. Я знаю, что то, что я хочу попробовать, довольно легко возможно, я просто не могу понять это.
Итак, допустим, у меня есть сотни отдельных диапазонов IP-адресов в формате 1.1.1.0 - 1.1.2.255 или в каком-либо другом формате (но не в формате CIDR, таком как 1.1.1.0/24).
Различные диапазоны не являются последовательными, поэтому между концом одного и началом следующего могут быть миллионы IP-адресов. При желании они могли бы / вместо этого были бы представлены в целочисленном формате (например, 16843008–16843519 в этом примере).
Не было бы известного наложения IP-адресов в другие диапазоны.
По сути, эти диапазоны представляют собой сетевые блоки ASN, если вам интересно. И мне нужно создать инструмент, чтобы определить, попадает ли какой-либо данный IP в один из этих диапазонов, но инструмент должен быть достаточно быстрым (в идеале менее 0,5 секунды).
Теперь, если у меня есть сотни или тысячи этих диапазонов, которые охватывают миллионы IP-адресов, и я хочу определить, находится ли данный IP-адрес в одном из диапазонов (или нет), что будет самым быстрым способом, при этом не слишком много памяти интенсивный?
Я могу придумать несколько вариантов:
Создайте HashSet, который содержит каждый IP-адрес из всех диапазонов, и просто сделайте для него contains (ip). Я ожидал, что там будет около 50 миллионов IP-адресов. Быстро, но кажется немного расточительным с точки зрения памяти?
Имейте TreeMap, ключ которого является начальным IP-адресом каждого диапазона, а значение - конечным IP-адресом. Пройдите по дереву и проверьте для каждого ключа, если тестовый IP-адрес больше, чем этот ключ, но меньше, чем следующий ключ. Если это так, то исследуйте значение (то есть конечный IP-адрес диапазона), и если IP-адрес меньше значения карты, тогда IP-адрес находится в диапазоне - если нет, нет смысла продолжать и можно предположить, что IP-адрес не в любом из диапазонов. Может ли, вероятно, бинарный поиск по ключам дерева быстрее прийти к выводу, а не проверка по порядку?
Другая идея - иметь HashMap, ключами которого будут все возможные подсети во всех диапазонах (я понимаю, что их будет много), например «123.123.123, 123.123.124, 123.123.125, 211.211.211, 211.211.215. "и т. д. Затем, если меня попросят проверить IP 123.123.124.144, я сначала смогу посмотреть, является ли его подсеть (123.123.124) ключом на карте. Значение карты может быть настраиваемым объектом, содержащим начальный и конечный IP-адреса диапазона, связанного с этой конкретной подсетью. Затем вы можете просто использовать это, чтобы проверить, подходит ли полный IP-адрес диапазону. Этот специальный объект будет совместно использоваться многими записями на карте, поскольку очевидно, что в данном диапазоне может быть много подсетей.
Итак, какие-нибудь мысли / идеи / мнения? Я чувствую, что моя вторая идея может быть хорошим способом пойти? Спасибо за информацию ... очень рад услышать ваши идеи!