I'm wondering if this is the best way to match a string that starts with a private IP address (Perl-style Regex):
(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])
Thanks much!
I'm wondering if this is the best way to match a string that starts with a private IP address (Perl-style Regex):
(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])
Thanks much!
I'm assuming you want to match these ranges:
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
You are missing some dots that would cause it to accept for example 172.169.0.0
even though this should not be accepted. I've fixed it below. Remove the new lines, it's just for readability.
(^127\.)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)
Also note that this assumes that the IP addresses have already been validated - it accepts things like 10.foobar
.
This is the same as the correct answer by Mark, but now including IPv6 private addresses.
/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/
I have generated this
REGEXP FOR CLASS A NETWORKS :
(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}
REGEXP FOR CLASS B NETWORKS :
(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 FOR CLASS C NETWORKS :
(192)\.(168)(\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]){2}
Let me know if you encounter any error
If you are sure of your output (say for example netstat) and you have no need to check about IP address validity because it is already done, then you can catch private ip addresses with this formula
grep -P "(10.|192.168|172.1[6-9].|172.2[0-9].|172.3[01].).* "
This is in case you decide to go with my comment, suggesting you don't use regexps. Untested (but probably works, or at least close), in 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
}
Note now how @private
is just data, which you can easily change. Or download on the fly from the Cymru Bogon Reference.
edit: It occurs to me that asking for a Perl regexp doesn't mean you know Perl, so the key line is there is the 'grep', which just loops over each private address range. You take your IP, bitwise and it with the netmask, and compare to the network address. If equal, its part of that private network.
Looks right. Personally, I'd change the first one to:
^127\.0
With this: (^127\.0\.0\.1)
you looking for anything that starts with 127.0.0.1
and will miss out on 127.0.0.2*
, 127.0.2.*
, 127.0.*
etc.
If you're looking for system.net defaultProxy and proxy bypasslist config that uses a proxy for external but uses direct connections for internal hosts (could do with some ipv6 support)...
<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>
here is what I use in 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})$')
You can remove the ^ and/or $ anchors if you wish.
I prefer the above regex because it weeds out invalid octets (anything above 255).
example usage:
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 this pattern was over 10% faster using pattern.matcher
:
^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\.