题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
题解参考了https://www.nowcoder.com/discuss/353149736708415488?sourceSSR=users的思路,但进行了一些自己的改进,也列出了一些说明,可以看做对以上题解的补充,帮助小白理解。
完整思路:
1.【0.*.*.*】和【127.*.*.*】的IP地址应当忽略,因此应该首先判断IP首位是否为0或127;
2.判断IP是否符合基本格式,即四位数字,由'.'隔开,每位数字在0-255之间;定义函数进行判断:
def IP_check(IP):
#对IP的基本检查:如果长度不为4或者某位数字不在0-255之间,说明格式不对
if len(IP)!=4:
return False
for i in IP:
if not i.isnumeric():
#不是数字的情况
return False
i=int(i)
if i<0 or i>255:
return False
return True
3.判断掩码是否合法;
这一步应该是整个流程中最容易出错的,反正我前几次提交都是因为非法掩码分类出错而失败的。
个人认为需要注意的点:32转成二进制为100000,255,255,255,32如果不考虑位数只拼接二进制字符串,是满足连续的1后面全是0的要求的,然而题目指明255.255.255.32是非法掩码,这说明32的二进制格式应该补齐位数到8位(也就是255转二进制后的位数),左边不足的补0,这样造成0后面有1的情况,导致冲突。因此我们遍历每位数字,将其转换为二进制后补齐位数到8再拼接字符串。拼接完成后,最后一位“1”应在第一位“0”前,如果找不到1或者0,说明掩码是非法的;
def mask_check(mask):
#对掩码的基本检查:全为1/全为0/0后有1均为非法
if not IP_check(mask):#掩码也要满足长度为4,每位在0-255之间的要求
return False
mask_string=""
for m in mask:
ms=bin(int(m))[2:]
mask_string+=ms.zfill(8) #.zfill:返回指定长度的字符串,原字符串右对齐,前面填充0
#找最后一个1和第一个0的位置;如果相差不是1则0后必有1,如果只有0或只有1,必然不可能相等(返回-1)
return mask_string.find("0")==mask_string.rfind("1")+1
4.判断IP是否属于私有IP地址;因为私有IP地址和A/B/C/D/E类地址不冲突,因此应当独立计算;
def private_check(IP):
if IP[0]=="10":
return True
elif IP[0]=="172" and 16<=int(IP[1])<=31:
return True
elif IP[0]=="192" and IP[1]=="168":
return True
else:
return False
5.判断IP属于哪一种类,并根据第一位的数值分类。在流程中,我们先判断IP是否符合基本格式,再进行种类的判断,因此每一位必然在0~255之间,所以除开ABCD以外的一定是E类,可以少写一个判断语句。
完整代码:
import sys
A = 0
B = 0
C = 0
D = 0
E = 0
F = 0 # 错误IP或错误掩码
P = 0 # 私有IP
#定义判断函数
def IP_check(IP):
#对IP的基本检查:如果长度不为4或者某位数字不在0-255之间,说明格式不对
if len(IP)!=4:
return False
for i in IP:
if not i.isnumeric():
#不是数字的情况
return False
i=int(i)
if i<0 or i>255:
return False
return True
def mask_check(mask):
#对掩码的基本检查:全为1/全为0/0后有1均为非法
if not IP_check(mask):#掩码也要满足长度为4,每位在0-255之间的要求
return False
mask_string=""
for m in mask:
ms=bin(int(m))[2:]
mask_string+=ms.zfill(8) #.zfill:返回指定长度的字符串,原字符串右对齐,前面填充0
#找最后一个1和第一个0的位置;如果相差不是1则0后必有1,如果只有0或只有1,必然不可能相等(返回-1)
return mask_string.find("0")==mask_string.rfind("1")+1
def private_check(IP):
if IP[0]=="10":
return True
elif IP[0]=="172" and 16<=int(IP[1])<=31:
return True
elif IP[0]=="192" and IP[1]=="168":
return True
else:
return False
for line in sys.stdin:
line = line.rstrip("\n")
a = line.split("~")
# 优先处理应该跳过的
IP = a[0].split(".")
if IP[0] == "0" or IP[0] == "127":
continue
#判断是否为非法地址
if not IP_check(IP):
F+=1
continue
#判断是否为非法掩码
if not mask_check(a[1].split(".")):
F+=1
continue
#IP地址和掩码都正确,进行分类
if private_check(IP):
P+=1
head=int(IP[0])
if 1<=head<=126:
A+=1
elif 128<=head<=191:
B+=1
elif 192<=head<=223:
C+=1
elif 224<=head<=239:
D+=1
else:
E+=1
print(A,B,C,D,E,F,P)

小天才公司福利 1152人发布