Identificador de endereço IP privado na expressão regular

Eu estou querendo saber se esta é a melhor maneira de coincidir com uma seqüência de caracteres que começa com um endereço IP privado (Regex estilo Perl):

(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1]) 

Muito obrigado!

Estou supondo que você queira corresponder a esses intervalos:

 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

Está faltando alguns pontos que o levariam a aceitar, por exemplo, o 172.169.0.0 mesmo que isso não devesse ser aceito. Eu consertei abaixo. Remova as novas linhas, é apenas para facilitar a leitura.

 (^127\.)| (^10\.)| (^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)| (^192\.168\.) 

Observe também que isso pressupõe que os endereços IP já foram validados – aceita itens como 10.foobar .

Esta é a mesma que a resposta correta por Mark, mas agora incluindo endereços privados IPv6.

 /(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/ 

Eu tenho gerado isso

REGEXP PARA REDES DE CLASSE A:

(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}

REGEXP PARA REDES DE CLASSE B:

(172)\.(1[6-9]|2[0-9]|3[0-1])(\.([2][0-5][0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}

REGEXP PARA REDES DE CLASSE C:

(192)\.(168)(\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]){2}

Deixe-me saber se você encontrar algum erro

Se você tem certeza de sua saída (digamos, por exemplo, netstat) e você não precisa verificar a validade do endereço IP, porque já está feito, então você pode capturar endereços IP privados com esta fórmula

grep -P “(10. | 192.168 | 172.1 [6-9]. | 172.2 [0-9]. | 172.3 [01].). *”

Isso é para o caso de você decidir ir com meu comentário, sugerindo que você não use regexps. Não testado (mas provavelmente funciona, ou pelo menos próximo), em 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 } 

Observe agora como @private é apenas dados, que você pode alterar facilmente. Ou faça o download na mosca da Referência Cymru Bogon .

Editar: Ocorreu-me que pedir um regexp Perl não significa que você conhece Perl, então a linha chave é que existe o ‘grep’, que apenas faz um loop em cada intervalo de endereço privado. Você pega seu IP, bit a bit e ele com a máscara de rede, e compara com o endereço da rede. Se igual, faz parte dessa rede privada.

Parece certo. Pessoalmente, eu mudaria o primeiro para:

 ^127\.0 

Com isto: (^127\.0\.0\.1) você está procurando por qualquer coisa que comece com 127.0.0.1 e perderá 127.0.0.2* , 127.0.2.* , 127.0.* Etc.

Se você está procurando por system.net defaultProxy e proxy bypasslist config que usa um proxy para externo, mas usa conexões diretas para hosts internos (poderia fazer com algum suporte ipv6) …

                   

aqui está o que eu uso em python:

 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})$') 

Você pode remover as âncoras ^ e / ou $, se desejar.

Eu prefiro o regex acima porque elimina octetos inválidos (qualquer coisa acima de 255).

exemplo de uso:

 if rfc1918.match(ip): print "ip is private" 
  //RegEx to check for the following ranges. IPv4 only //172.16-31.xxx.xxx //10.xxx.xxx.xxx //169.254.xxx.xxx //192.168.xxx.xxx var regex = /(^127\.)|(^(0)?10\.)|(^172\.(0)?1[6-9]\.)|(^172\.(0)?2[0-9]\.)|(^172\.(0)?3[0-1]\.)|(^169\.254\.)|(^192\.168\.)/; 

FWIW este padrão foi mais de 10% mais rápido usando pattern.matcher :

 ^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\.