1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/toktok-jip-common

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 12:04 113aaf8

Суперполезный jip-common: поддерживает IPv4 и IPv6, производительность на высоте

С постепенным распространением IPv6 многие компании внутри своих приложений должны постепенно поддерживать IPv6. Однако, поскольку большинство разработчиков ранее учитывали только IPv4, обновление поддержки IPv6 может быть трудоёмким процессом, который может привести к большому количеству раздутого кода if else.

Этот ip-анализатор jip-common скрывает от верхних слоёв приложения понятия типа IP и диапазона IP, что делает обновление более удобным.

Подробнее:

  1. Gitee: https://gitee.com/toktok
  2. Блог: http://www.easysb.cn

Введение в 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);

4.5 Сценарии использования: разность IP-адресов

Разность 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);

4.6 Сценарии использования: сопоставление IP и группы

Это наиболее распространённый сценарий, когда группа содержит множество 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"); // Можно удалить

4.7 Сценарии использования: проверка добавленных IP-адресов на корректность

При добавлении IP-групп обычно проверяют правильность введённых IP-адресов. Библиотека JIP предоставляет простой класс анализа для проверки правильности IP-адреса. Если встречается ошибка, анализ останавливается и возвращается сообщение об ошибке:

String check = JIPAddressCheckUtils.checkConvertIpObject(addressList, departmentIPSegment.getIpList());
if (StringUtils.isNotBlank(check)) { // Если есть ошибка, она будет показана
    return check;
}

Также при обновлении IP-группы необходимо проверить, не конфликтует ли обновление с существующими группами. Для этого можно использовать следующие методы:

  • Для всех групп создать большой набор деревьев T.
  • Проверить каждый IP-сегмент в обновлённой группе на наличие в других группах в наборе деревьев T.

4.8 Сценарии использования: форматирование вывода

Форматирование вывода влияет только на формат отображения 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

4.9 Сценарий 9: Развернуть IP-сегмент

Если необходимо развернуть 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);

Пять. Участие в разработке

  1. Fork этого репозитория.
  2. Оставьте комментарий на моём блоге: http://www.easysb.cn.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/toktok-jip-common.git
git@api.gitlife.ru:oschina-mirror/toktok-jip-common.git
oschina-mirror
toktok-jip-common
toktok-jip-common
master