Суперполезный jip-common: поддерживает IPv4 и IPv6, производительность на высоте
С постепенным распространением IPv6 многие компании внутри своих приложений должны постепенно поддерживать IPv6. Однако, поскольку большинство разработчиков ранее учитывали только IPv4, обновление поддержки IPv6 может быть трудоёмким процессом, который может привести к большому количеству раздутого кода if else.
Этот ip-анализатор jip-common скрывает от верхних слоёв приложения понятия типа IP и диапазона IP, что делает обновление более удобным.
Подробнее:
Введение в jip-common
jip-common не только поддерживает IPv4 и IPv6, но также поддерживает анализ различных форматов IP (см. следующий раздел). Он позволяет верхним слоям приложения скрывать тип IP и даже отдельный IP или диапазон IP, делая код верхнего уровня более лаконичным.
Поскольку большинству бизнес-приложений требуется выполнять операции с наборами IP-адресов, библиотека JIP также предоставляет функции для работы с наборами IP, такие как объединение, пересечение, объединение и разность, максимально удовлетворяя потребности бизнеса.
Обычно, чтобы определить, к какому продукту принадлежит IP-адрес, разработчики часто преобразуют диапазон IP-адресов в отдельные IP-адреса и сопоставляют их с помощью карты для быстрого поиска. Этот метод подходит для случаев с небольшим количеством IP-адресов. Но для больших объёмов данных или при работе с IPv6 этот метод становится неэффективным. Поэтому модуль JIP использует характеристики бинарного дерева и красно-чёрного дерева, вместо того чтобы преобразовывать диапазоны IP в отдельные адреса, обеспечивая быстрый поиск и экономию памяти и времени.
Maven, Gradle и другие.
Пожалуйста, обратитесь к ссылке: https://jitpack.io/#jekkay/jip-common/
Поддерживаемые форматы
Для строк, начинающихся с #, JIP по умолчанию рассматривает их как комментарии и пропускает анализ. В качестве разделителей между IP-адресами можно использовать \r\n, \r, \n или ;.
3.1 Поддержка анализа IP-адресов
Существует четыре формата поддержки IPv4:
Формат | Пример | Примечание |
---|---|---|
Отдельный IP | 1.1.1.1 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Диапазон IP с маской подсети | 1.1.1.1/24 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Простой начальный диапазон IP | 1.1.1.1-20 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Полный начальный и конечный диапазон IP | 1.1.1.1–1.1.1.20 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Существует четыре формата поддержки IPv6:
Формат | Пример | Примечание |
---|---|---|
Отдельный IP | 8888::226:2dff:fefa:0 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Диапазон IP с маской подсети | 8888::226:2dff:fefa:0/24 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Простой начальный диапазон IP | 8888::226:2dff:fefa:0–20 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
Полный начальный и конечный диапазон IP | 8888::226:2dff:fefa:0–8888::226:2dff:fefa:20 | Комментарии не должны содержать точку с запятой, так как она будет интерпретирована как разделитель между несколькими IP-адресами |
3.2 Наборы IP
JIP предоставляет интерфейс JIPAddress для одного IP и набор JIPAddressSet для коллекций IP. Набор основан на характеристиках бинарных деревьев и красно-чёрных деревьев, позволяя выполнять стандартные операции над коллекциями. Важно отметить, что этот набор может одновременно содержать все форматы, поддерживаемые в разделе 3.1, то есть верхние слои приложения не нужно заботиться о том, является ли IP адресом IPv4 или IPv6 и является ли это отдельным IP или диапазоном IP.
Быстрое использование
Подробные руководства обычно читают меньше людей, поэтому я просто объясню, какие преимущества JIP может предоставить в зависимости от сценариев использования.
4.1 Сценарий 1: Анализ IP-адресов
Отдельный IP или отдельный диапазон IP:
Чтобы проанализировать отдельный IP-адрес или диапазон IP-адресов, вы можете напрямую использовать:
JIPAddress a1 = JIPAddressUtils.toIpObject("10.0.0.5/24 # Это комментарий");
System.out.println(a1.toString()); // 10.0.0.5/24
JIPAddress a2 = JIPAddressUtils.toIpObject("10.0.0.0-255");
JIPAddress a3 = JIPAddressUtils.toIpObject("8888::226:2dff:fefa:10-8888::226:2dff:fefa:20")
Если вы хотите узнать тип результата анализа, вы можете вызвать функцию getIpType(), которая вернёт перечисление. Пожалуйста, обратитесь к исходному коду для определения перечисления.
System.out.println(a1.getIpType())
Несколько IP или несколько диапазонов IP:
Если вам нужно проанализировать несколько IP-адресов или диапазонов IP-адресов, вы можете непосредственно использовать следующий метод:
JIPAddressSet addressSet = JIPAddressUtils.buildAddressSet(
"101.35.129.0;101.35.132.0/24;101.35.133.0/24;101.35.134.0/24;101.35.135.0/24;");
Вы можете сразу создать набор IP, используя различные разделители [\r\n, \r, \n и ;] для разделения нескольких IP-адресов и диапазонов IPv4 и IPv6. В наборе также можно добавлять комментарии без каких-либо проблем.
Проверка действительности IP-адреса:
JIPAddressUtils.isValidIPAddress("1.1.1.1")
4.2 Сценарий 2: Объединение IP-адресов
Объединение IP-адресов предназначено для уменьшения количества записей IP. Например, 1.1.1.0–100 и 1.1.1.100–255 можно объединить в 1.1.1.0/24. JIP предоставляет функцию объединения для отдельных IP-адресов (диапазонов) и множественных IP-адресов (диапазонов), которая реализуется JIPAddressCombiner.
Ниже приведён пример объединения отдельных IP-адресов:
JIPAddress jipAddress1 = JIPAddressUtils.toIpObject("1.1.1.0");
JIPAddress jipAddress2 = JIPAddressUtils.toIpObject("1.1.1.1-255");
List<JIPAddress> result = JIPAddressCombiner.combine(jipAddress1, jipAddress2);
// Вывод — 1.1.1.0/24
Аналогично, объединение нескольких IP-адресов также работает аналогичным образом.
4.3 Сценарий 3: Пересечение IP-адресов
Функция пересечения IP-адресов не ограничивается отдельными IP-адресами (диапазонами), но также может применяться к нескольким IP-адресам (диапазонам), и эта функция реализуется JIPAddressIntersecter.
Приведён пример пересечения отдельных IP-адресов:
JIPAddress jipAddress1 = JIPAddressUtils.toIpObject("1.1.1.15-30");
JIPAddress jipAddress2 = JIPAddressUtils.toIpObject("1.1.1.10-20");
List<JIPAddress> result = JIPAddressIntersecter.intersect(jipAddress1, jipAddress2);
// вывод — 1.1.1.15–20
Как и в случае с объединением, пересечение нескольких IP-адресов работает аналогично. ### 4.4 Сценарии использования: объединение IP-адресов
IP-объединение адресов не ограничивается объединением одного IP (сегмента), но также может пересекать несколько IP (сегментов). Эта функция в основном выполняется с помощью JIPAddressUnioner.
Например, объединение двух отдельных IP-адресов:
JIPAddress address1 = JIPAddressUtils.toIpObject("101.35.135.0/24");
JIPAddress address2 = JIPAddressUtils.toIpObject("101.35.136.0/21");
List<JIPAddress> addressList = JIPAddressUnioner.union(address1, address2);
Разность IP-адресов не ограничивается одним IP (сегментом), но также может быть применена к нескольким IP (сегментам). Эта функция выполняется с использованием JIPAddressSubtracter.
Пример разности двух отдельных IP-адресов:
JIPAddress address1 = JIPAddressUtils.toIpObject("101.35.135.0/24");
JIPAddress address2 = JIPAddressUtils.toIpObject("101.35.135.0/28");
List<JIPAddress> addressList = JIPAddressSubtracter.subtract(address1, address2);
Это наиболее распространённый сценарий, когда группа содержит множество IP-сегментов, и необходимо быстро найти соответствующий IP для каждой группы. Обычно мы используем метод хэширования IP-сегментов по одному и помещаем их в HashMap. Однако этот метод имеет недостаток: если есть сегмент A или даже сегмент 0.0.0.0/0, программа может использовать большое количество памяти и даже вызвать сбой программы.
Рекомендуется использовать набор модулей библиотеки JIP для создания небольшого красно-чёрного дерева, как показано ниже:
// Создание пустого набора
JIPAddressSet tmpJipAddressSet = JIPAddressUtils.buildEmptyAddressSet();
for (IdcIpSegment idcIpSegment : tmpIdcIpSegmentList) {
// Помещаем список IP-адресов этой группы в набор вместе с данными внешнего ключа
JIPAddressUtils.addIpList(tmpJipAddressSet, idcIpSegment.getIpList(), idcIpSegment);
}
Чтобы найти IP, соответствующий группе, можно использовать следующий код:
JIPAddress find = jipAddressSet.findIp("1.1.1.23")
Результатом поиска будет 1.1.10/24, а затем можно получить соответствующую группу:
IdcIpSegment findGroup = ((IdcIpSegment) find.getData())
Эти две операции можно выполнить за один шаг, используя эквивалентный метод:
IdcIpSegment findGroup = jipAddressSet.findIpData("1.1.1.23", IdcIpSegment.class);
Обратите внимание, что если есть несколько совпадающих результатов, findIp возвращает только первый. Также обратите внимание, что набор можно преобразовать в List, вызвав метод all(), который проходит через все элементы в порядке обхода.
Для удаления IP из набора используется метод deleteIp(). Важно отметить, что удаление происходит на основе полного совпадения, в то время как поиск основан на частичном совпадении (достаточно пересечения):
JIPAddressSet tmpJipAddressSet = JIPAddressUtils.buildEmptyAddressSet();
JIPAddressUtils.addIpList(tmpJipAddressSet,“1.1.1.0/24”, idcIpSegment);
tmpJipAddressSet.deleteIp("1.1.1.0"); // Невозможно удалить
tmpJipAddressSet.deleteIp("1.1.1.0/24"); // Можно удалить
tmpJipAddressSet.deleteIp("1.1.1.0-255"); // Можно удалить
При добавлении IP-групп обычно проверяют правильность введённых IP-адресов. Библиотека JIP предоставляет простой класс анализа для проверки правильности IP-адреса. Если встречается ошибка, анализ останавливается и возвращается сообщение об ошибке:
String check = JIPAddressCheckUtils.checkConvertIpObject(addressList, departmentIPSegment.getIpList());
if (StringUtils.isNotBlank(check)) { // Если есть ошибка, она будет показана
return check;
}
Также при обновлении IP-группы необходимо проверить, не конфликтует ли обновление с существующими группами. Для этого можно использовать следующие методы:
Форматирование вывода влияет только на формат отображения IP-сегмента, но не влияет на вывод отдельного IP. Всегда выводится только один IP.
Форматирование:
JIPAddress address = JIPAddressUtils.toIpObject("1.2.3.0-255");
System.out.println(address.toString()); // ===> 1.2.3.0-255
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_WITH_MASK_FIRST)); // ==> 1.2.3.0/24
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_SIMPLE_FIRST)); // ===> 1.2.3.0-255
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_FULL_FIRST)); // 1.2.3.0-1.2.3.255
Форматированный вывод определяет, какой формат использовать для отображения IP. Если указанный формат не может быть использован, автоматически применяется исходный формат. Например, для IP-сегмента 1.2.3.1-3 невозможно использовать формат с маской, поэтому он не будет работать, даже если указать формат mask:
JIPAddress address = JIPAddressUtils.toIpObject("1.2.3.1-3");
System.out.println(address.toString()); // ====> 1.2.3.1-3
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_WITH_MASK_FIRST)); // ====> 1.2.3.1-3
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_SIMPLE_FIRST)); // ====> 1.2.3.1-3 ```
System.out.println(JIPAddressUtils.toIpListString(address, IPFormatType.SEGMENT_FULL_FIRST)); // ====> 1.2.3.1-1.2.3.3
Если необходимо развернуть IP-сегмент в виде отдельных IP-адресов, обычно используется метод JIPAddressUtils.expandIpList, как показано ниже:
List<JIPAddress> ipList = JIPAddressUtils.expandIpList(
JIPAddressUtils.toIpObject("1.1.1.1/24"), 10);
Внутри происходит итерация с помощью iterator, и в итоге получаются первые 10 отдельных IP (второй параметр указывает максимальное количество IP после расширения, 0 означает отсутствие ограничения).
Кроме работы с одним IP-сегментом, можно также развернуть один или несколько IP-адресов (сегментов), как показано ниже для получения всех отдельных IP:
List<JIPAddress> ipList = JIPAddressUtils.expandIpList(JIPAddressUtils.buildAddressSet("1.1.1.1/30\n2.2.2.2/30"), 0);
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )