题解 | #识别有效的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)
全部评论

相关推荐

点赞 评论 收藏
分享
04-28 11:34
西北大学 运营
牛客4396号:不好意思,这个照片猛一看像丁真
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务