![](/img/trans.png)
[英]How do I get the private IP address of the computer that I am using in python?
[英]How do you determine if an IP address is private, in Python?
在 Python 中,确定 IP 地址(例如'127.0.0.1'
或'10.98.76.6'
)是否在专用网络上的最佳方法是什么? 代码听起来并不难写。 但是可能存在比立即显而易见的更多边缘情况,并且需要考虑 IPv6 支持等。是否有现有的库可以做到这一点?
从 Python 3.3 开始,您可以使用 stdlib 中的ipaddress 模块。
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1').is_private
True
如果使用 Python 2.6 或更高版本,我强烈建议使用此模块的反向移植。
查看IPy模块。 如果有一个函数iptype()
似乎可以执行您想要的操作:
>>> from IPy import IP
>>> ip = IP('127.0.0.0/30')
>>> ip.iptype()
'PRIVATE'
您可以使用http://tools.ietf.org/html/rfc1918和http://tools.ietf.org/html/rfc3330 自行检查。 如果你有 127.0.0.1 你只需要&
它与掩码(假设255.0.0.0
)并查看该值是否与任何专用网络的网络地址匹配。 所以使用inet_pton你可以做到: 127.0.0.1 & 255.0.0.0 = 127.0.0.0
这是说明这一点的代码:
from struct import unpack
from socket import AF_INET, inet_pton
def lookup(ip):
f = unpack('!I',inet_pton(AF_INET,ip))[0]
private = (
[ 2130706432, 4278190080 ], # 127.0.0.0, 255.0.0.0 http://tools.ietf.org/html/rfc3330
[ 3232235520, 4294901760 ], # 192.168.0.0, 255.255.0.0 http://tools.ietf.org/html/rfc1918
[ 2886729728, 4293918720 ], # 172.16.0.0, 255.240.0.0 http://tools.ietf.org/html/rfc1918
[ 167772160, 4278190080 ], # 10.0.0.0, 255.0.0.0 http://tools.ietf.org/html/rfc1918
)
for net in private:
if (f & net[1]) == net[0]:
return True
return False
# example
print(lookup("127.0.0.1"))
print(lookup("192.168.10.1"))
print(lookup("10.10.10.10"))
print(lookup("172.17.255.255"))
# outputs True True True True
另一种实现是计算所有私有块的 int 值:
from struct import unpack
from socket import AF_INET, inet_pton
lookup = "127.0.0.1"
f = unpack('!I',inet_pton(AF_INET,lookup))[0]
private = (["127.0.0.0","255.0.0.0"],["192.168.0.0","255.255.0.0"],["172.16.0.0","255.240.0.0"],["10.0.0.0","255.0.0.0"])
for net in private:
mask = unpack('!I',inet_aton(net[1]))[0]
p = unpack('!I',inet_aton(net[0]))[0]
if (f & mask) == p:
print lookup + " is private"
这是@Kurt 建议的正则表达式方法的固定版本,包括@RobEvans 建议的修复
^127.\\d{1,3}.\\d{1,3}.\\d{1,3}$
^10.\\d{1,3}.\\d{1,3}.\\d{1,3}$
^192.168.\\d{1,3}.\\d{1,3}$
^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$
def is_ip_private(ip): # https://en.wikipedia.org/wiki/Private_network priv_lo = re.compile("^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$") priv_24 = re.compile("^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$") priv_20 = re.compile("^192\\.168\\.\\d{1,3}.\\d{1,3}$") priv_16 = re.compile("^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$") res = priv_lo.match(ip) or priv_24.match(ip) or priv_20.match(ip) or priv_16.match(ip) return res is not None
这不会是 kubernetes 内部使用的 100.xxx 范围
我在cuckoo 中找到了这个。不需要安装新模块。只需导入两个内置模块:socket 和 struct。 并使用下面的功能。
def _is_private_ip(self, ip):
"""Check if the IP belongs to private network blocks.
@param ip: IP address to verify.
@return: boolean representing whether the IP belongs or not to
a private network block.
"""
networks = [
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.88.99.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"240.0.0.0/4",
"255.255.255.255/32",
"224.0.0.0/4",
]
for network in networks:
try:
ipaddr = struct.unpack(">I", socket.inet_aton(ip))[0]
netaddr, bits = network.split("/")
network_low = struct.unpack(">I", socket.inet_aton(netaddr))[0]
network_high = network_low | 1 << (32 - int(bits)) - 1
if ipaddr <= network_high and ipaddr >= network_low:
return True
except Exception,err:
continue
return False
问这个问题几天后,我发现了这个谷歌项目ipaddr-py ,它似乎具有一些相同的功能,用于确定地址是否是私有的( is_rfc1918
)。 显然,这将是 Python 3.1 的标准。
如果你想避免导入一个模块,你可以应用一个简单的正则表达式:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.