在python和bash中处理IP和端口

时间:2014-02-20 12:55:27

标签: python bash ip-address

使用python和bash,我想完成两件事:

  1. 需要将[fec2 :: 10]:80格式的ipv6地址和端口组合拆分为fec2 :: 10和80。

  2. 考虑到IP地址和端口组合,我需要确定IP是v4还是v6地址。例如:1.2.3.4:80和[fec2 :: 10]:80

  3. 请建议一种方法。

    谢谢!

    示例代码:

    #!/usr/bin/env python
    
    import optparse
    
    def main():
        server = "[fec1::1]:80"
        if server.find("[", 0, 2) == -1:
           print "IPv4"
           ip, port = server.split(':')
        else:
           print "IPv6"
           new_ip, port = server.rsplit(':', 1)
           print new_ip
           ip = new_ip.strip('[]')
    
        print ip
        print port
    
    if __name__ == '__main__':
        main()
    

    这适用于所有情况,除非在没有端口的情况下指定输入。例如:10.78.49.50和[fec2 :: 10]

    有任何解决此问题的建议吗?

3 个答案:

答案 0 :(得分:4)

假设your_input"[fec2::10]:80""1.2.3.4:80"相似,则可以轻松拆分端口并找出IP地址:

#!/usr/bin/env python3
from ipaddress import ip_address

ip, separator, port = your_input.rpartition(':')
assert separator # separator (`:`) must be present
port = int(port) # convert to integer
ip = ip_address(ip.strip("[]")) # convert to `IPv4Address` or `IPv6Address` 
print(ip.version) # print ip version: `4` or `6`

答案 1 :(得分:1)

您可以使用urlparse(在3.x中称为urllib.parse)将URL分成每个组件:

>>> from urlparse import urlparse
>>> ipv4address = urlparse("http://1.2.3.4:80")
>>> ipv4address
ParseResult(scheme='http', netloc='1.2.3.4:80', path='', params='', query='', fragment='')
>>> ipv6address = urlparse("http://[fec2::10]:80")
>>> ipv6address
ParseResult(scheme='http', netloc='[fec2::10]:80', path='', params='', query='', fragment='')

然后,您可以通过使用rfind

查找最后一个冒号的索引来关闭端口
>>> ipv4address.netloc.rfind(':')
7
>>> ipv4address.netloc[:7], ipv4address.netloc[8:]
('1.2.3.4', '80')
>>> ipv6address.netloc.rfind(':')
10
>>> ipv6address.netloc[:10], ipv6address.netloc[11:]
('[fec2::10]', '80')

确定它的类型应该像if ':' in that_split_tuple[0]一样简单,对吗? (不是100%肯定,因为我已经了解了如何在URL中编写IPv6地址。)

最后,从IPv6地址中删除括号很简单,有很多方法可以执行此操作:

>>> ipv6address.netloc[:10].replace('[', '').replace(']', '')
'fec2::10'
>>> ipv6address.netloc[:10].strip('[]')
'fec2::10'

修改:由于您表示担心并不总是有端口号,因此您可以使用regular expression显着简化:

>>> import re
>>> f = lambda(n): re.split(r"(?<=\]):" if n.startswith('[') else r"(?<=\d):", n)
>>> f(ipv4address.netloc)
['1.2.3.4', '80']
>>> f(ipv6address.netloc)
['[fec2::10]', '80']
>>> f("1.2.3.4")
['1.2.3.4']
>>> f("[fec2::10]")
['[fec2::10]']

(我很难用我的正则表达式更聪明,因此是内联三元组。)

答案 2 :(得分:0)

这是我提出的代码。它看起来冗长而费力,但它解决了所有可能的输入场景。任何强调/更好的建议都是非常受欢迎的:)

#!/usr/bin/env python

import optparse

def main():
    server = "[fec1::1]:80"

    if server.find("[", 0, 2) == -1:
       print "IPv4"
       if server.find(":", 0, len(server)) == -1:
          ip = server
          port = ""
       else:
          ip, port = server.split(':')
    else:
       print "IPv6"
       index = server.find("]", 0, len(server))
       if index == -1:
          print "Something wrong"
          new_ip = ""
          port = ""
       else:
          if server.find(":", index, len(server)) == -1:
             new_ip = server
             port = ""
          else:
             new_ip, port = server.rsplit(':', 1)
       print new_ip
       ip = new_ip.strip('[]')

    print ip
    print port

if __name__ == '__main__':
    main()