python解法

1. 思路分析

根据题目意思,一共写了3个功能函数来完成此任务: 0. 我设计了一个字典来存储最终的统计结果:ip_dic = {'A':0, 'B':0, 'C':0, 'D':0, 'E':0, 'fault':0, 'private':0},其实也可以用列表来存储,我偏向用字典存储。

  1. 首先第一个函数check(ip_mac, ip_dic)检查输入的ip 和mac格式是否正确,下一步分类基于此检查,如果检查格式正确则进入下一步统计,否则读取下一行输入。这里有两个个点需要注意,第一个点:输入的ip和mac只要有一个是错误的,就直接归为错误输入类,不再进行下一步分类步骤,开始读取下一行输入;第二个点:'255.255.255.255' '0.0.0.0'的掩码是不正确的。
  2. 格式正确后,调用ips(ip, ip_dic)对IP进行分类,分别是A/B/C/D/E 5类,还有错误类加上私有类,共七类。
  3. _bin(seq)是一个功能函数,用来把输入的seq(ip/mac)转换为二进制格式结果的字符串输出,比如输入‘5’,输出‘00000101’ 最后就是把这些功能函数串起来,完成整体的分类统计工作,也就是count_type()函数了。

2. 代码

def check(ip_mac, ip_dic):
    '''
    This function is used to check the format of input ips and input macs, if the format is normal, return True and ip_dic;
    if the format is abnormal, return False and ip_dic.
    '''
    ip = ip_mac[0]
    ip_flag = False
    if '..' in ip:
        ip_flag = True
    elif ip.split('.', maxsplit=1)[0] == '127' or ip.split('.', maxsplit=1)[0] == '0':
        return ip_dic, False
    else:
        pass
    mac = ip_mac[1]
    mac_flag = False
    mac_li = [bin(int(x))[2:] for x in mac.split('.')]
    mac_seq = ''
    for i in mac_li:
        length = len(i)
        if length < 8:
            mac_seq +='0'*(8-length) + i
        else:
            mac_seq += i 
#     print(mac_seq)
    if '01' in mac_seq or mac_seq == '0'*32 or mac_seq == '1'*32:
        mac_flag = True
    if ip_flag or mac_flag:
        ip_dic['fault'] += 1
        return ip_dic, False
    else:
        return ip_dic, True

def _bin(seq):
    '''
    This function is used to transfrom the decimal format of ips and macs into binary string format, which finally 
    give out the 32 bit binary like strings.
    '''
    seq_li = [bin(int(x))[2:] for x in seq.split('.')]
    bin_seq = ''
    for i in seq_li:
        length = len(i)
        if length < 8:
            bin_seq += '0'*(8-length) + i
        else:
            bin_seq += i
    return bin_seq


def ips(ip, ip_dic):
    '''
    This function is used to classify the input ip, which can be devide into 5 types.
    A类地址1.0.0.0~126.255.255.255;
    B类地址128.0.0.0~191.255.255.255;
    C类地址192.0.0.0~223.255.255.255;
    D类地址224.0.0.0~239.255.255.255;
    E类地址240.0.0.0~255.255.255.255
    '''
    if '..' in ip:
        ip_dic['fault'] += 1
    elif _bin(ip) >= _bin('1.0.0.0') and _bin(ip) <= _bin('126.255.255.255'):
        ip_dic['A'] += 1
        if _bin(ip) >= _bin('10.0.0.0') and _bin(ip) <= _bin('10.255.255.255'):
            ip_dic['private'] += 1
    elif _bin(ip) >= _bin('128.0.0.0') and _bin(ip) <= _bin('191.255.255.255'):
        ip_dic['B'] += 1
        if _bin(ip) >= _bin('172.16.0.0') and _bin(ip) <= _bin('172.31.255.255'):
            ip_dic['private'] += 1
    elif _bin(ip) >= _bin('192.0.0.0') and _bin(ip) <= _bin('223.255.255.255'):
        ip_dic['C'] += 1
        if _bin(ip) >= _bin('192.168.0.0') and _bin(ip) <= _bin('192.168.255.255'):
            ip_dic['private'] += 1
    elif _bin(ip) >= _bin('224.0.0.0') and _bin(ip) <= _bin('239.255.255.255'):
        ip_dic['D'] += 1
    elif _bin(ip) >= _bin('240.0.0.0') and _bin(ip) <= _bin('255.255.255.255'):
        ip_dic['E'] += 1
    else:
        ip_dic['fault'] += 1
    return ip_dic

def count_type():
    '''
    This function is used to count the type of ips. In this function there is a dictionary, which its elements are types of classification.
    During the process, the final result will be recorded in this dictionary.
    '''
    ip_dic = {'A':0, 'B':0, 'C':0, 'D':0, 'E':0, 'fault':0, 'private':0}
    while True:
        try:
            # 1. 读取输入数据
            ip_mac = input().split('~')
            # 2. 检查输入ip 与 mac格式是否正确
            ip_dic, flag = check(ip_mac, ip_dic)
            # 3. 检查完毕,开始分类
            if flag:
                # 3.1 ips为ip的分类函数
                ip = ip_mac[0]
    #             print(ip)
                ip_dic = ips(ip, ip_dic)
    #             print(mac)
        except:
            # 4. 所有输入完毕,输出统计结果
            for i in ip_dic.values():
                print(i, end=' ')
#             print('\n' + str(ip_dic))
            break

if __name__ == '__main__':
    count_type()