كيف يمكنني التحقق مما إذا كان IP في شبكة في بيثون؟
-
03-07-2019 - |
سؤال
بالنظر إلى عنوان IP (على سبيل المثال 192.168.0.1) ، كيف يمكنني التحقق مما إذا كان في شبكة (قل 192.168.0.0/24) في بيثون؟
هل هناك أدوات عامة في بيثون لمعالجة عنوان IP؟ أشياء مثل عمليات البحث عن المضيف ، IP AddDress إلى int ، عنوان الشبكة مع Netmask إلى int وما إلى ذلك؟ نأمل في مكتبة بيثون القياسية لمدة 2.5.
المحلول
هذه المقالة يظهر أنه يمكنك القيام بذلك مع socket
و struct
وحدات دون الكثير من الجهد الإضافي. أضفت قليلاً إلى المقالة على النحو التالي:
import socket,struct
def makeMask(n):
"return a mask of n bits as a long integer"
return (2L<<n-1) - 1
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('L',socket.inet_aton(ip))[0]
def networkMask(ip,bits):
"Convert a network address to a long integer"
return dottedQuadToNum(ip) & makeMask(bits)
def addressInNetwork(ip,net):
"Is an address in a network"
return ip & net == net
address = dottedQuadToNum("192.168.1.1")
networka = networkMask("10.0.0.0",24)
networkb = networkMask("192.168.0.0",24)
print (address,networka,networkb)
print addressInNetwork(address,networka)
print addressInNetwork(address,networkb)
هذا المخرجات:
False
True
إذا كنت تريد فقط وظيفة واحدة تأخذ سلاسل ، فستبدو هكذا:
import socket,struct
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('L',socket.inet_aton(netaddr))[0] & ((2L<<int(bits)-1) - 1)
return ipaddr & netmask == netmask
نصائح أخرى
أحب الاستخدام Netaddr من أجل هذا:
from netaddr import CIDR, IP
if IP("192.168.0.1") in CIDR("192.168.0.0/24"):
print "Yay!"
كما أشار Arno_V في التعليقات ، فإن إصدار NetAddr جديد يفعل مثل هذا:
from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
print "Yay!"
استخدام ipaddress (في stdlib منذ 3.3, في PYPI لمدة 2.6/2.7):
>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1') in ipaddress.ip_network('192.168.0.0/24')
True
إذا كنت تريد تقييم أ كثير من عناوين IP بهذه الطريقة ، ربما تريد حساب Netmask مقدمًا ، مثل
n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)
ثم ، لكل عنوان ، احسب التمثيل الثنائي مع واحد من
a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0] # IPv4 only
أخيرًا ، يمكنك ببساطة التحقق من:
in_network = (a & mask) == netw
هذا الرمز يعمل بالنسبة لي على Linux X86. لم أفكر حقًا في أي مشكلات إنديان ، لكنني اختبرتها ضد وحدة "iPaddr" باستخدام أكثر من 200 ألف عنوان IP تم اختبارها مقابل 8 سلاسل شبكات مختلفة ، ونتائج iPaddr هي نفسها مثل هذا الرمز.
def addressInNetwork(ip, net):
import socket,struct
ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
netstr, bits = net.split('/')
netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
return (ipaddr & mask) == (netaddr & mask)
مثال:
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/16')
True
>>> print addressInNetwork('10.9.8.7', '10.9.1.0/24')
False
ل Python3
In [64]: ipaddress.IPv4Address('192.168.1.1') in ipaddress.IPv4Network('192.168.0.0/24')
Out[64]: False
جربت حل ديف ويب ولكن ضربت بعض المشاكل:
الأهم من ذلك - يجب فحص المباراة عن طريق وصلة عنوان IP مع القناع ، ثم التحقق من النتيجة تطابق عنوان الشبكة بالضبط. ليس وينج عنوان IP مع عنوان الشبكة كما حدث.
لاحظت أيضًا أن تجاهل السلوك الإنديان على افتراض أن الاتساق سيوفر لك فقط سيعمل على أقنعة على حدود الثماني ( /24 ، /16). من أجل الحصول على أقنعة أخرى ( /23 ، /21) تعمل بشكل صحيح ، أضفت "أكبر من" إلى أوامر الهيكل وتغيير الكود لإنشاء القناع الثنائي للبدء بكل "1" والتحول اليسار بواسطة (32 قناع ).
أخيرًا ، أضفت التحقق البسيط من أن عنوان الشبكة صالح للقناع وطباعة تحذير فقط إذا لم يكن كذلك.
ها هي النتيجة:
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('>L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('>L',socket.inet_aton(netaddr))[0]
ipaddr_masked = ipaddr & (4294967295<<(32-int(bits))) # Logical AND of IP address and mask will equal the network address if it matches
if netmask == netmask & (4294967295<<(32-int(bits))): # Validate network address is valid for mask
return ipaddr_masked == netmask
else:
print "***WARNING*** Network",netaddr,"not valid with mask /"+bits
return ipaddr_masked == netmask
أنا لست من محبي استخدام الوحدات النمطية عندما لا تكون هناك حاجة إليها. هذه المهمة تتطلب الرياضيات البسيطة فقط ، لذا إليك وظيفتي البسيطة للقيام بالمهمة:
def ipToInt(ip):
o = map(int, ip.split('.'))
res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
return res
def isIpInSubnet(ip, ipNetwork, maskLength):
ipInt = ipToInt(ip)#my test ip, in int form
maskLengthFromRight = 32 - maskLength
ipNetworkInt = ipToInt(ipNetwork) #convert the ip network into integer form
binString = "{0:b}".format(ipNetworkInt) #convert that into into binary (string format)
chopAmount = 0 #find out how much of that int I need to cut off
for i in range(maskLengthFromRight):
if i < len(binString):
chopAmount += int(binString[len(binString)-1-i]) * 2**i
minVal = ipNetworkInt-chopAmount
maxVal = minVal+2**maskLengthFromRight -1
return minVal <= ipInt and ipInt <= maxVal
ثم لاستخدامه:
>>> print isIpInSubnet('66.151.97.0', '66.151.97.192',24)
True
>>> print isIpInSubnet('66.151.97.193', '66.151.97.192',29)
True
>>> print isIpInSubnet('66.151.96.0', '66.151.97.192',24)
False
>>> print isIpInSubnet('66.151.97.0', '66.151.97.192',29)
هذا كل شيء ، هذا أسرع بكثير من الحلول المذكورة أعلاه مع الوحدات النمطية المضمنة.
الجواب المقبول لا يعمل ... مما يجعلني غاضبًا. القناع للخلف ولا يعمل مع أي أجزاء ليست كتلة بسيطة 8 بت (على سبيل المثال /24). لقد قمت بتكييف الجواب ، وهو يعمل بشكل جيد.
import socket,struct
def addressInNetwork(ip, net_n_bits):
ipaddr = struct.unpack('!L', socket.inet_aton(ip))[0]
net, bits = net_n_bits.split('/')
netaddr = struct.unpack('!L', socket.inet_aton(net))[0]
netmask = (0xFFFFFFFF >> int(bits)) ^ 0xFFFFFFFF
return ipaddr & netmask == netaddr
فيما يلي وظيفة تُرجع سلسلة ثنائية منقط للمساعدة ipcalc
انتاج.
def bb(i):
def s = '{:032b}'.format(i)
def return s[0:8]+"."+s[8:16]+"."+s[16:24]+"."+s[24:32]
على سبيل المثال:
ليس في المكتبة القياسية لـ 2.5 ، لكن iPaddr يجعل هذا الأمر سهلاً للغاية. أعتقد أنه في 3.3 تحت اسم ipaddress.
import ipaddr
a = ipaddr.IPAddress('192.168.0.1')
n = ipaddr.IPNetwork('192.168.0.0/24')
#This will return True
n.Contains(a)
رمز مارك صحيح تقريبا. نسخة كاملة من الرمز هي -
def addressInNetwork3(ip,net):
'''This function allows you to check if on IP belogs to a Network'''
ipaddr = struct.unpack('=L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('=L',socket.inet_aton(calcDottedNetmask(int(bits))))[0]
network = struct.unpack('=L',socket.inet_aton(netaddr))[0] & netmask
return (ipaddr & netmask) == (network & netmask)
def calcDottedNetmask(mask):
bits = 0
for i in xrange(32-mask,32):
bits |= (1 << i)
return "%d.%d.%d.%d" % ((bits & 0xff000000) >> 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))
من الواضح من نفس المصادر على النحو الوارد أعلاه ...
ملاحظة مهمة للغاية هي أن الكود الأول يحتوي على خلل صغير - عنوان IP 255.255.255.255 يظهر أيضًا كـ IP صالح لأي شبكة فرعية. كان لدي وقت من الوقت في الحصول على هذا الرمز للعمل وبفضل مارك على الإجابة الصحيحة.
يمكن أن يسبب الاعتماد على وحدة "الهيكل" مشاكل في أحجام endian-nys و type ، وليس هناك حاجة إليها. ولا socket.inet_aton (). يعمل Python بشكل جيد للغاية مع عناوين IP المنقطة:
def ip_to_u32(ip):
return int(''.join('%02x' % int(d) for d in ip.split('.')), 16)
أحتاج إلى القيام بمطابقة IP على كل مقبس قبول () ، مقابل مجموعة كاملة من الشبكات المصدر المسموح بها ، لذلك أنا أقنعة وشبكات محسوبة ، كمناسبات: أعداد صحيحة:
SNS_SOURCES = [
# US-EAST-1
'207.171.167.101',
'207.171.167.25',
'207.171.167.26',
'207.171.172.6',
'54.239.98.0/24',
'54.240.217.16/29',
'54.240.217.8/29',
'54.240.217.64/28',
'54.240.217.80/29',
'72.21.196.64/29',
'72.21.198.64/29',
'72.21.198.72',
'72.21.217.0/24',
]
def build_masks():
masks = [ ]
for cidr in SNS_SOURCES:
if '/' in cidr:
netstr, bits = cidr.split('/')
mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
net = ip_to_u32(netstr) & mask
else:
mask = 0xffffffff
net = ip_to_u32(cidr)
masks.append((mask, net))
return masks
ثم يمكنني معرفة ما إذا كان عنوان IP معين ضمن إحدى هذه الشبكات:
ip = ip_to_u32(ipstr)
for mask, net in cached_masks:
if ip & mask == net:
# matched!
break
else:
raise BadClientIP(ipstr)
لا حاجة للواردات النمطية ، والرمز هو جداً سريع في المطابقة.
من netaddr import all_matching_cidrs
>>> from netaddr import all_matching_cidrs
>>> all_matching_cidrs("212.11.70.34", ["192.168.0.0/24","212.11.64.0/19"] )
[IPNetwork('212.11.64.0/19')]
هنا هو استخدام هذه الطريقة:
>>> help(all_matching_cidrs)
Help on function all_matching_cidrs in module netaddr.ip:
all_matching_cidrs(ip, cidrs)
Matches an IP address or subnet against a given sequence of IP addresses and subnets.
@param ip: a single IP address or subnet.
@param cidrs: a sequence of IP addresses and/or subnets.
@return: all matching IPAddress and/or IPNetwork objects from the provided
sequence, an empty list if there was no match.
في الأساس ، يمكنك تقديم عنوان IP كوسيطة أولى وقائمة من CIDRs كوسيطة ثانية. يتم إرجاع قائمة من الزيارات.
#This works properly without the weird byte by byte handling def addressInNetwork(ip,net): '''Is an address in a network''' # Convert addresses to host order, so shifts actually make sense ip = struct.unpack('>L',socket.inet_aton(ip))[0] netaddr,bits = net.split('/') netaddr = struct.unpack('>L',socket.inet_aton(netaddr))[0] # Must shift left an all ones value, /32 = zero shift, /0 = 32 shift left netmask = (0xffffffff << (32-int(bits))) & 0xffffffff # There's no need to mask the network address, as long as its a proper network address return (ip & netmask) == netaddr
الإجابة المختارة لها خطأ.
فيما يلي الرمز الصحيح:
def addressInNetwork(ip, net_n_bits):
ipaddr = struct.unpack('<L', socket.inet_aton(ip))[0]
net, bits = net_n_bits.split('/')
netaddr = struct.unpack('<L', socket.inet_aton(net))[0]
netmask = ((1L << int(bits)) - 1)
return ipaddr & netmask == netaddr & netmask
ملحوظة: ipaddr & netmask == netaddr & netmask
بدلاً من ipaddr & netmask == netmask
.
أنا أيضا استبدال ((2L<<int(bits)-1) - 1)
مع ((1L << int(bits)) - 1)
, ، كما يبدو الأخير أكثر فهمًا.
إليكم الفصل الذي كتبته لأطول بادئة مطابقة:
#!/usr/bin/env python
class Node:
def __init__(self):
self.left_child = None
self.right_child = None
self.data = "-"
def setData(self, data): self.data = data
def setLeft(self, pointer): self.left_child = pointer
def setRight(self, pointer): self.right_child = pointer
def getData(self): return self.data
def getLeft(self): return self.left_child
def getRight(self): return self.right_child
def __str__(self):
return "LC: %s RC: %s data: %s" % (self.left_child, self.right_child, self.data)
class LPMTrie:
def __init__(self):
self.nodes = [Node()]
self.curr_node_ind = 0
def addPrefix(self, prefix):
self.curr_node_ind = 0
prefix_bits = ''.join([bin(int(x)+256)[3:] for x in prefix.split('/')[0].split('.')])
prefix_length = int(prefix.split('/')[1])
for i in xrange(0, prefix_length):
if (prefix_bits[i] == '1'):
if (self.nodes[self.curr_node_ind].getRight()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getRight()
else:
tmp = Node()
self.nodes[self.curr_node_ind].setRight(len(self.nodes))
tmp.setData(self.nodes[self.curr_node_ind].getData());
self.curr_node_ind = len(self.nodes)
self.nodes.append(tmp)
else:
if (self.nodes[self.curr_node_ind].getLeft()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getLeft()
else:
tmp = Node()
self.nodes[self.curr_node_ind].setLeft(len(self.nodes))
tmp.setData(self.nodes[self.curr_node_ind].getData());
self.curr_node_ind = len(self.nodes)
self.nodes.append(tmp)
if i == prefix_length - 1 :
self.nodes[self.curr_node_ind].setData(prefix)
def searchPrefix(self, ip):
self.curr_node_ind = 0
ip_bits = ''.join([bin(int(x)+256)[3:] for x in ip.split('.')])
for i in xrange(0, 32):
if (ip_bits[i] == '1'):
if (self.nodes[self.curr_node_ind].getRight()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getRight()
else:
return self.nodes[self.curr_node_ind].getData()
else:
if (self.nodes[self.curr_node_ind].getLeft()):
self.curr_node_ind = self.nodes[self.curr_node_ind].getLeft()
else:
return self.nodes[self.curr_node_ind].getData()
return None
def triePrint(self):
n = 1
for i in self.nodes:
print n, ':'
print i
n += 1
وهنا برنامج اختبار:
n=LPMTrie()
n.addPrefix('10.25.63.0/24')
n.addPrefix('10.25.63.0/16')
n.addPrefix('100.25.63.2/8')
n.addPrefix('100.25.0.3/16')
print n.searchPrefix('10.25.63.152')
print n.searchPrefix('100.25.63.200')
#10.25.63.0/24
#100.25.0.3/16
شكرا لك على البرنامج النصي الخاص بك!
لدي عمل طويل على جعل كل شيء يعمل ... لذلك أنا أشاركه هنا
- يعد استخدام فئة NetAddr أبطأ 10 مرات من استخدام التحويل الثنائي ، لذلك إذا كنت ترغب في استخدامه في قائمة كبيرة من IP ، فيجب عليك عدم استخدام فئة Netaddr
وظيفة makemask لا تعمل! العمل فقط ل/8 ،/16 ،/24
السابق:بت = "21" ؛ socket.inet_ntoa (struct.pack ('= l' ، (2l << int (bits) -1) - 1))
"255.255.31.0" في حين يجب أن يكون 255.255.248.0لذلك استخدمت وظيفة أخرى calcdottednetmask (قناع) من http://code.activestate.com/recipes/576483-convert-subnetmask-from-cidr-notation-to-dotdecima/
السابق:
#!/usr/bin/python
>>> calcDottedNetmask(21)
>>> '255.255.248.0'
- مشكلة أخرى هي عملية المطابقة إذا كان عنوان IP ينتمي إلى شبكة! يجب أن تكون العملية الأساسية للمقارنة (iPaddr & netmask) و (الشبكة و Netmask).
على سبيل المثال: في الوقت الحالي ، فإن الوظيفة خاطئة
#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
>>>True which is completely WRONG!!
لذا فإن وظيفة addringInnetwork الجديدة الخاصة بي تبدو شبيهة:
#!/usr/bin/python
import socket,struct
def addressInNetwork(ip,net):
'''This function allows you to check if on IP belogs to a Network'''
ipaddr = struct.unpack('=L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netmask = struct.unpack('=L',socket.inet_aton(calcDottedNetmask(bits)))[0]
network = struct.unpack('=L',socket.inet_aton(netaddr))[0] & netmask
return (ipaddr & netmask) == (network & netmask)
def calcDottedNetmask(mask):
bits = 0
for i in xrange(32-int(mask),32):
bits |= (1 > 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))
والآن ، الجواب صحيح !!
#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
False
آمل أن يساعد ذلك الآخرين ، وتوفير الوقت لهم!
فيما يتعلق بكل ما سبق ، أعتقد أن socket.inet_aton () يعيد بايت بترتيب الشبكة ، وبالتالي فإن الطريقة الصحيحة لتفريغها هي على الأرجح
struct.unpack('!L', ... )
الحل السابق له خطأ في IP & net == net. بحث IP الصحيح هو IP & netmask = net
رمز bugfixed:
import socket
import struct
def makeMask(n):
"return a mask of n bits as a long integer"
return (2L<<n-1) - 1
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('L',socket.inet_aton(ip))[0]
def addressInNetwork(ip,net,netmask):
"Is an address in a network"
print "IP "+str(ip) + " NET "+str(net) + " MASK "+str(netmask)+" AND "+str(ip & netmask)
return ip & netmask == net
def humannetcheck(ip,net):
address=dottedQuadToNum(ip)
netaddr=dottedQuadToNum(net.split("/")[0])
netmask=makeMask(long(net.split("/")[1]))
return addressInNetwork(address,netaddr,netmask)
print humannetcheck("192.168.0.1","192.168.0.0/24");
print humannetcheck("192.169.0.1","192.168.0.0/24");
هناك واجهة برمجة تطبيقات تسمى الشبكات الفرعية المتاحة في بيثون تقوم بهذه المهمة بشكل جيد للغاية. هذا مثال بسيط :
import SubnetTree
t = SubnetTree.SubnetTree()
t.insert("10.0.1.3/32")
print("10.0.1.3" in t)
import socket,struct
def addressInNetwork(ip,net):
"Is an address in a network"
ipaddr = struct.unpack('!L',socket.inet_aton(ip))[0]
netaddr,bits = net.split('/')
netaddr = struct.unpack('!L',socket.inet_aton(netaddr))[0]
netmask = ((1<<(32-int(bits))) - 1)^0xffffffff
return ipaddr & netmask == netaddr & netmask
print addressInNetwork('10.10.10.110','10.10.10.128/25')
print addressInNetwork('10.10.10.110','10.10.10.0/25')
print addressInNetwork('10.10.10.110','10.20.10.128/25')
$ python check-subnet.py
خطأ شنيع
حقيقي
خطأ شنيع
لا أعرف أي شيء في المكتبة القياسية ، لكن pysubnettree هي مكتبة Python التي ستقوم بمطابقة الشبكة الفرعية.
من مصادر مختلفة أعلاه ، ومن بحثي الخاص ، هكذا حصلت على الشبكة الفرعية وحساب العنوان. هذه القطع كافية لحل السؤال والأسئلة الأخرى ذات الصلة.
class iptools:
@staticmethod
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('>L', socket.inet_aton(ip))[0]
@staticmethod
def numToDottedQuad(n):
"convert long int to dotted quad string"
return socket.inet_ntoa(struct.pack('>L', n))
@staticmethod
def makeNetmask(mask):
bits = 0
for i in xrange(32-int(mask), 32):
bits |= (1 << i)
return bits
@staticmethod
def ipToNetAndHost(ip, maskbits):
"returns tuple (network, host) dotted-quad addresses given"
" IP and mask size"
# (by Greg Jorgensen)
n = iptools.dottedQuadToNum(ip)
m = iptools.makeMask(maskbits)
net = n & m
host = n - mask
return iptools.numToDottedQuad(net), iptools.numToDottedQuad(host)
ها هو الكود الخاص بي
# -*- coding: utf-8 -*-
import socket
class SubnetTest(object):
def __init__(self, network):
self.network, self.netmask = network.split('/')
self._network_int = int(socket.inet_aton(self.network).encode('hex'), 16)
self._mask = ((1L << int(self.netmask)) - 1) << (32 - int(self.netmask))
self._net_prefix = self._network_int & self._mask
def match(self, ip):
'''
判断传入的 IP 是不是本 Network 内的 IP
'''
ip_int = int(socket.inet_aton(ip).encode('hex'), 16)
return (ip_int & self._mask) == self._net_prefix
st = SubnetTest('100.98.21.0/24')
print st.match('100.98.23.32')
إذا كنت لا ترغب في استيراد الوحدات الأخرى التي يمكنك الذهاب إليها:
def ip_matches_network(self, network, ip):
"""
'{:08b}'.format(254): Converts 254 in a string of its binary representation
ip_bits[:net_mask] == net_ip_bits[:net_mask]: compare the ip bit streams
:param network: string like '192.168.33.0/24'
:param ip: string like '192.168.33.1'
:return: if ip matches network
"""
net_ip, net_mask = network.split('/')
net_mask = int(net_mask)
ip_bits = ''.join('{:08b}'.format(int(x)) for x in ip.split('.'))
net_ip_bits = ''.join('{:08b}'.format(int(x)) for x in net_ip.split('.'))
# example: net_mask=24 -> compare strings at position 0 to 23
return ip_bits[:net_mask] == net_ip_bits[:net_mask]
لقد جربت مجموعة فرعية واحدة من الحلول المقترحة في هذه الإجابات .. بدون نجاح ، قمت أخيرًا بتكييف الرمز المقترح وأصلحته وكتبت وظيفتي الثابتة.
لقد اختبرت ذلك وأعمل على الأقل على البنى الداخلية الصغيرة-egx86-إذا كان أي شخص يحب تجربة بنية إنديان كبيرة ، فالرجاء إعطائي التعليقات.
IP2Int
الرمز يأتي من هذا المشنور, ، الطريقة الأخرى هي إصلاح بالكامل (لحالات الاختبار الخاصة بي) العمل للمقترحات السابقة في هذا السؤال.
الرمز:
def IP2Int(ip):
o = map(int, ip.split('.'))
res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
return res
def addressInNetwork(ip, net_n_bits):
ipaddr = IP2Int(ip)
net, bits = net_n_bits.split('/')
netaddr = IP2Int(net)
bits_num = int(bits)
netmask = ((1L << bits_num) - 1) << (32 - bits_num)
return ipaddr & netmask == netaddr & netmask
نأمل مفيدًا ،