正则表达式中的私有IP地址标识符

时间:2010-05-11 19:55:09

标签: regex ip-address private

我想知道这是否是匹配以私有IP地址开头的字符串的最佳方式(Perl风格的Regex):

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

非常感谢!

11 个答案:

答案 0 :(得分:51)

我假设你想要匹配这些范围:

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之类的内容。

答案 1 :(得分:17)

这与Mark的正确答案相同,但现在包括IPv6私有地址。

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

答案 2 :(得分:9)

我已经生成了这个

CLASS A NETWORKS的REGEXP:

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

B类网络的REGEXP:

(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}

CLASS C NETWORKS的REGEXP:

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

如果您遇到任何错误,请告诉我

如果您确定输出(例如netstat)并且您无需检查IP地址有效性,因为它已经完成,那么您可以使用此公式捕获私有IP地址

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

答案 3 :(得分:3)

看起来正确。就个人而言,我将第一个更改为:

^127\.0 

使用此(^127\.0\.0\.1),您需要查找以127.0.0.1开头并且错过127.0.0.2*127.0.2.*127.0.*等的任何内容。

答案 4 :(得分:3)

如果您决定使用我的评论,建议您不要使用正则表达式。在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 Reference即时下载。

编辑:我发现要求Perl regexp并不意味着你知道Perl,所以关键行是'grep',它只是遍历每个私有地址范围。您使用IP,按位并使用网络掩码,并与网络地址进行比较。如果相等,那就是那个私人网络的一部分。

答案 5 :(得分:1)

如果您正在寻找使用外部代理但使用内部主机的直接连接的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>

答案 6 :(得分:1)

这是我在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})$')

如果愿意,您可以删除^和/或$ anchors。

我更喜欢上面的正则表达式,因为它会清除无效的八位字节(任何高于255的值)。

示例用法:

if rfc1918.match(ip):
    print "ip is private"

答案 7 :(得分:1)

晚10年。归功于Mark ByersbrampEdwardblueyeduser3177026Justinkarmakaze

回答TLDR

仅开始

请删除换行符-这只是为了使其更易于阅读:

^(?:
127\.|
0?10\.|
172\.0?1[6-9]\.|
172\.0?2[0-9]\.|
172\.0?3[0-2]\.|
192\.168\.|
169\.254\.|
::1|
[fF][cCdD][0-9a-fA-F]{2}:|
[fF][eE][8-9aAbB][0-9a-fA-F]:
)

括号中的?:表示该括号未被捕获,可能会使它变得更快一些。

整个IP(十进制,前导零可选,最多三位数)

请删除换行符-这只是为了使其更易于阅读:

\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[0-2]\.(?: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][8-9aAbB][0-9a-fA-F](?:[:][0-9a-fA-F]{0,4}){0,7}
)
(?:\/([789]|1?[0-9]{2}))?
\b

https://regex101.com/r/JCLOZL/7

详细信息

IPv4

  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是否可以有前导零。

带前导零(十进制)的IPv4

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

带前导零(八进制)的IPv4

我的正则表达式不支持。为了使您的程序更完美,请检查并警告用户八进制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.0330254.0021.0062.0041在不同的工具上相同。在MacOS上使用ping进行了测试。

当然,您也可以在某些工具中将十进制(无前导零)与八进制(至少一个前导零)混合。 :S

IPv6

fc00:0000:… to fdff:ffff:… is fc00::/7
fe80:0000:… to febf:ffff:… is fe80::/10  # link-local addresses

示例:

fdff:1234:abcd:5678:effe:9098:dcba:7654 or more explicit:
fdff:1234:abcd:5678:effe:9098:dcba:7654/128

不完整的链接列表

当我来到这里时,我不知道:

答案 8 :(得分:0)

     //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\.)/;

答案 9 :(得分:0)

如果超过一位数,您需要一个结尾分隔符才能获得整个第 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])$

答案 10 :(得分:-1)

FWIW使用pattern.matcher时,此模式的速度提高了10%以上:

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