Мне интересно, лучший ли это способ сопоставить строку, начинающуюся с частного IP-адреса (регулярное выражение в стиле Perl):
(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])
Спасибо большое!
Мне интересно, лучший ли это способ сопоставить строку, начинающуюся с частного IP-адреса (регулярное выражение в стиле Perl):
(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])
Спасибо большое!
Я предполагаю, что вы хотите сопоставить эти диапазоны:
127. 0.0.0 – 127.255.255.255 127.0.0.0 /8 10. 0.0.0 – 10.255.255.255 10.0.0.0 /8 172. 16.0.0 – 172. 31.255.255 172.16.0.0 /12 192.168.0.0 – 192.168.255.255 192.168.0.0 /16
Вам не хватает некоторых точек, которые заставят его принять, например, 172.169.0.0
, даже если это не должно быть принято. Я исправил это ниже. Удалите новые строки, это просто для удобства чтения.
(^127\.)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)
Также обратите внимание, что это предполагает, что IP-адреса уже проверены — он принимает такие вещи, как 10.foobar
.
'(^127\\.0\\.0\\.1)|(^10\\.)|(^172\\.1[6-9]\\.)|(^172\\.2[0-9]\\.)|(^172\\.3[0-1]\\.)|(^192\\.168\\.)'
- person Phani; 23.05.2015
(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.1[6-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.2[0-9]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^172\.3[0-1]{1}[0-9]{0,1}\.[0-9]{1,3}\.[0-9]{1,3}$)|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)
- person dr.dimitru; 15.01.2016
^(10|127|169\.254|172\.1[6-9]|172\.2[0-9]|172\.3[0-1]|192\.168)\.
- person karmakaze; 28.03.2016
^(10|127|169\.254|172\.(1[6-9]|2[0-9]|3[0-1])|192\.168)\.
(или даже ^1(0|27|69\.254|72\.(1[6-9]|2[0-9]|3[0-1])|92\.168)\.
, но это может быть слишком далеко).
- person Nicolas Melay; 12.10.2020
Это то же самое, что и правильный ответ Марка, но теперь включает частные адреса IPv6.
/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/
^[fF][cCdD]
- я соответствующим образом редактирую ответ.
- person blueyed; 15.03.2015
/
в начале и в конце сценария предполагает, что вы используете выражение на каком-то языке, таком как Javascript, но это недопустимо на других языках. Несмотря на это, более короткая версия (и без косых черт) ^(127\.)|(192\.168\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(::1$)|([fF][cCdD])
- person Mariano Ruiz; 28.06.2017
я сгенерировал это
REGEXP ДЛЯ СЕТЕЙ КЛАССА А:
(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}
REGEXP ДЛЯ СЕТЕЙ КЛАССА B:
(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}
REGEXP ДЛЯ СЕТЕЙ КЛАССА C:
(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){2}
Дайте мне знать, если вы столкнетесь с какой-либо ошибкой
Если вы уверены в своем выводе (скажем, например, netstat) и вам не нужно проверять действительность IP-адреса, потому что это уже сделано, вы можете поймать частные IP-адреса с помощью этой формулы
grep -P "(10.|192.168|172.1[6-9].|172.2[0-9].|172.3[01].).* "
[2][0-5][0-5]
для диапазона от 200 до 255, такие числа, как 206 до 209 и 216 до 219 и т. д., не будут совпадать. Вам придется заменить это на ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
.
- person kielabokkie; 15.03.2014
вот что я использую в питоне:
rfc1918 = re.compile('^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){3}|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){2})$')
При желании вы можете удалить якоря ^ и/или $.
Я предпочитаю приведенное выше регулярное выражение, потому что оно отсеивает недопустимые октеты (все, что выше 255).
пример использования:
if rfc1918.match(ip):
print "ip is private"
Это на тот случай, если вы решите согласиться с моим комментарием, предлагающим не использовать регулярные выражения. Непроверено (но, вероятно, работает или, по крайней мере, близко) в Perl:
@private = (
{network => inet_aton('127.0.0.0'), mask => inet_aton('255.0.0.0') },
{network => inet_aton('192.168.0.0'), mask => inet_aton('255.255.0.0') },
# ...
);
$ip = inet_aton($ip_text);
if (grep $ip & $_->{mask} == $_->{network}, @private) {
# ip address is private
} else {
# ip address is not private
}
Обратите внимание, что @private
— это просто данные, которые вы можете легко изменить. Или загрузите на лету из справочника Cymru Bogon.
edit: мне приходит в голову, что запрос регулярного выражения Perl не означает, что вы знаете Perl, поэтому ключевая строка заключается в том, что есть «grep», который просто перебирает каждый диапазон частных адресов. Вы берете свой IP-адрес, побитовый и с сетевой маской, и сравниваете с сетевым адресом. Если равны, это часть этой частной сети.
Выглядит правильно. Лично я бы изменил первый на:
^127\.0
При этом: (^127\.0\.0\.1)
вы ищете все, что начинается с 127.0.0.1
и пропускает 127.0.0.2*
, 127.0.2.*
, 127.0.*
и т. д.
на 10 лет позже. Кредиты Mark Byers
, bramp
, Edward
, blueyed
, user3177026
, Justin
, karmakaze
, Ron Maupin
.
Пожалуйста, удалите разрывы строк - это просто для удобства чтения:
^(?:
127\.|
0?10\.|
172\.0?1[6-9]\.|
172\.0?2[0-9]\.|
172\.0?3[01]\.|
192\.168\.|
169\.254\.|
::1|
[fF][cCdD][0-9a-fA-F]{2}:|
[fF][eE][89aAbB][0-9a-fA-F]:
)
?:
в начале круглой скобки означает, что эта круглая скобка не захватывается и может сделать ее немного быстрее.
Пожалуйста, будьте осторожны с обратной косой чертой. В Postgres, например. вы должны использовать строку E и должны экранировать обратную косую черту с помощью обратной косой черты - или просто используйте [.]
вместо E'\\.'
!
Пожалуйста, удалите разрывы строк - это просто для удобства чтения:
\b(
127\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
0?10\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?1[6-9]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?2[0-9]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
172\.0?3[01]\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
192\.168\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
169\.254\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|
::1|
[fF][cCdD][0-9a-fA-F]{2}(?:[:][0-9a-fA-F]{0,4}){0,7}|
[fF][eE][89aAbB][0-9a-fA-F](?:[:][0-9a-fA-F]{0,4}){0,7}
)
(?:\/([789]|1?[0-9]{2}))?
\b
https://regex101.com/r/JCLOZL/14 (Резервная копия: https://etherpad.wikimedia.org/p/JCLOZL)
127.0.0.0 to 127.255.255.255 is 127.0.0.0/8 # localhost, loopback etc.
10.0.0.0 to 10.255.255.255 is 10.0.0.0/8 # approximately/formerly class A
172.16.0.0 to 172.31.255.255 is 172.16.0.0/12 # approximately/formerly class B
192.168.0.0 to 192.168.255.255 is 192.168.0.0/16 # approximately/formerly class C
169.254.0.0 to 169.254.255.255 is 169.254.0.0/16 # link-local addresses since 2005
Пример:
172.17.50.33 or more explicit:
172.17.50.33/32
Я не уверен, что часть за косой чертой может иметь начальные нули (маловероятно), но IP может иметь начальные нули.
127.000.000.000 to 127.255.255.255 is 127.000.000.000/8 # localhost, loopback etc.
010.000.000.000 to 010.255.255.255 is 010.000.000.000/8 # approx/formerly class A
172.016.000.000 to 172.031.255.255 is 172.016.000.000/12 # approx/formerly class B
192.168.000.000 to 192.168.255.255 is 192.168.000.000/16 # approx/formerly class C
169.254.000.000 to 169.254.255.255 is 169.254.000.000/16 # link-local addresses
Пример:
172.017.050.033 or more explicit:
172.017.050.033/32
Не поддерживается в моем регулярном выражении. Чтобы сделать вашу программу идеальной, проверьте и предупредите пользователя о восьмеричных IP-адресах и/или более трех цифр!
0177.0000.0000.0000 to 0177.0377.0377.0377 is 0177.0000.0000.0000/8 # loopback
0012.0000.0000.0000 to 0012.0377.0377.0377 is 0012.0000.0000.0000/8 # A
0254.0020.0000.0000 to 0254.0037.0377.0377 is 0254.0020.0000.0000/12 # B
0300.0250.0000.0000 to 0300.0250.0377.0377 is 0300.0250.0000.0000/16 # C
0251.0376.0000.0000 to 0251.0376.0377.0377 is 0251.0376.0000.0000/16 # link-local
Пример:
0254.0021.0062.0041 or more explicit:
0254.0021.0062.0041/32
Да, 172.017.050.033
совпадает с 0254.0021.0062.0041
на разных инструментах. Протестировано с ping
на macOS.
Конечно, в некоторых инструментах вы также можете смешивать десятичную (без нуля в начале) с восьмеричной (по крайней мере, с одним нулем в начале). :С
fc00:0000:… to fdff:ffff:… is fc00::/7
fe80:0000:… to febf:ffff:… is fe80::/10 # link-local addresses
Это может быть не совсем то, что вы хотите, потому что:
Частные IPv4-адреса определены RFC 1918, Распределение адресов для частных интернетов, и адреса используются во многих сетях по всему миру. ULA-адреса IPv6 должны быть уникальными (U в ULA), чтобы их нельзя было повторно использовать в нескольких местах, поэтому они должны иметь 40 случайных битов в глобальном идентификаторе, что дает высокие ожидания уникальности.
Все адреса из публичного интернета будут в диапазоне от 2000::
до 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
(2000::/3
). Вам нужно правильно замаскировать адрес, чтобы увидеть, находится ли он в общедоступном диапазоне, а затем сделать то же самое для непубличных диапазонов в общедоступном диапазоне. Если он проходит тест общедоступного диапазона, он должен провалить закрытые диапазоны в общедоступном диапазоне. Если он проходит все это, это публичный адрес. Устройства IoT также получают глобальные (общедоступные) IPv6-адреса. Смысл IPv6 в том, что существует достаточно адресов, чтобы каждый интерфейс на каждом устройстве получил глобальный IPv6-адрес, восстанавливая способ, которым IP был изначально разработан (больше не нужно обходиться без NAT).
Некоторые внутренние адреса вашего веб-сервера будут адресами Link-Local (fe80::/10
), и можно назначить адреса ULA (fc00::/7
из которых вы можете назначить из fd00::/8
с определенными ограничениями) для трафика, который никогда не будет разрешен в общедоступном Интернете.
Пример:
fdff:1234:abcd:5678:effe:9098:dcba:7654 or more explicit:
fdff:1234:abcd:5678:effe:9098:dcba:7654/128
Когда я пришел сюда, я не знал о:
224.0.0.0/24
)Если вы ищете system.net defaultProxy и конфигурацию обхода прокси-серверов, которая использует прокси-сервер для внешних, но использует прямые подключения для внутренних хостов (можно сделать с некоторой поддержкой ipv6)...
<system.net>
<defaultProxy enabled="true">
<proxy proxyaddress="http://proxycluster.privatedomain.net:8080" bypassonlocal="True" />
<bypasslist>
<!-- exclude local host -->
<add address="^(http|https)://localhost$" />
<!-- excludes *.privatedomain.net -->
<add address="^(http|https)://.*\.privatedomain\.net$" />
<!-- excludes simple host names -->
<add address="^(http|https)://[a-z][a-z0-9\-_]*$" />
<!-- exclude private network addresses 192.168, 172.16..31 through 31, 127.* etc. -->
<add address="^(http|https)://((((127)|(10))\.[0-9]+\.[0-9]+\.[0-9]+)|(((172\.(1[6-9]|2[0-9]|3[0-1]))|(192\.168))\.[0-9]+\.[0-9]+))$"/>
</bypasslist>
</defaultProxy>
<connectionManagement>
<add address="*" maxconnection="10" />
</connectionManagement>
</system.net>
Вам нужен конечный разделитель, чтобы получить весь 4-й октет, если это более одной цифры.
^(10.([0-9][0-9]?|[0-1][0-9]?[0-9]?|2[0-4]?[0-9]?|25[0-5])|172.(1[6-9]|2[0-9]|3[0-1])|192.168).([0-9][0-9]?|[0-1][0-9]?[0-9]?|2[0-4]?[0-9]?|25[0-5]).([0-9][0-9]?|[0-1][0-9]?[0-9]?|2[0-4]?[0-9]?|25[0-5])$
FWIW этот шаблон был более чем на 10% быстрее при использовании pattern.matcher
:
^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\.
^
означает не в этом контексте, поэтому стоит отметить: каждый^
в вашем выражении просто привязывает совпадение к началу строки. В традиционном регулярном выражении нет простого способа сказать не эту строку, хотя Perl-совместимые/PCRE-выражения имеют отрицательный просмотр вперед с(?!...)
- person tripleee   schedule 14.12.2017