Private IP Address Identifier in Regular Expression

后端 未结 10 1257
伪装坚强ぢ
伪装坚强ぢ 2020-12-01 09:14

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\\.)|(         


        
相关标签:
10条回答
  • 2020-12-01 09:31

    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.

    0 讨论(0)
  • 2020-12-01 09:34

    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.

    0 讨论(0)
  • 2020-12-01 09:34

    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"
    
    0 讨论(0)
  • 2020-12-01 09:35

    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>
    
    0 讨论(0)
  • 2020-12-01 09:42

    10 years late. Credits to Mark Byers, bramp, Edward, blueyed, user3177026, Justin.

    Answer TLDR

    Beginning only

    Please remove the line breaks - this is just to make it easier to read:

    ^(?:
    127\.|
    0?1[02]\.|
    172\.0?1[6-9]\.|
    172\.0?2[0-9]\.|
    172\.0?3[0-7]\.|
    192\.168\.|
    ::1|
    [fF][cCdD][0-9a-fA-F]{2}
    )
    

    The ?: at the beginning of the parenthesis means that this parenthesis is not captured and may make it a bit faster.

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

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

    Details

    IPv4

      127.0.0.0 to 127.255.255.255 is   127.0.0.0/8   # localhost 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
    

    Example:

    172.17.50.33 or more explicit:
    172.17.50.33/32
    

    I'm not sure if the part behind the slash can have leading zeros (unlikely), but the IP can have leading zeros.

    IPv4 with leading zeros (decimal)

    127.000.000.000 to 127.255.255.255 is 127.000.000.000/8   # localhost etc.
    010.000.000.000 to 010.255.255.255 is 010.000.000.000/8   # approximately/formerly class A
    172.016.000.000 to 172.031.255.255 is 172.016.000.000/12  # approximately/formerly class B
    192.168.000.000 to 192.168.255.255 is 192.168.000.000/16  # approximately/formerly class C
    

    Example:

    172.017.050.033 or more explicit:
    172.017.050.033/32
    

    IPv4 with leading zeros (octal)

    127.000.000.000 to 127.255.255.255 is 127.000.000.000/8   # localhost etc.
    012.000.000.000 to 012.255.255.255 is 012.000.000.000/8   # approximately/formerly class A
    172.020.000.000 to 172.037.255.255 is 172.020.000.000/12  # approximately/formerly class B
    192.168.000.000 to 192.168.255.255 is 192.168.000.000/16  # approximately/formerly class C
    

    Example:

    172.021.062.041 or more explicit:
    172.021.062.041/32
    

    Yes, 010.000.000.001 is the same as 012.000.000.001 on different tools. Tested with ping on macOS.

    IPv6

    fc00… to fdff… is fc00::/7
    

    Example:

    fdff:1234:abcd:5678:effe:9098:dcba:7654 or more explicit:
    fdff:1234:abcd:5678:effe:9098:dcba:7654/128
    
    0 讨论(0)
  • 2020-12-01 09:43

    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.

    0 讨论(0)
提交回复
热议问题