使用Python,我想完成两件事:
需要将 [fec2::10]:80 格式的 ipv6 地址和端口组合拆分为 fec2::10 和 80。
给定一个 IP 地址和端口组合,我需要确定该 IP 是 v4 还是 v6 地址。例如:1.2.3.4:80 和 [fec2::10]:80
请建议一种方法。
谢谢!
示例代码:
#!/usr/bin/env python
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]
有什么建议可以解决这个问题吗?
假设
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`
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'
编辑:由于您表示担心并不总是有端口号,因此您可以通过使用正则表达式:
来显着简化>>> 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]']
(我无法更聪明地使用我的正则表达式,因此使用内联三元。)
这是我想出的代码。它看起来冗长而费力,但它解决了所有可能的输入场景。任何关于压缩/更好的建议都是非常受欢迎的:)
#!/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()
ip, port = server.rsplit(':', 1)
适用于 IPv4 和 IPv6!