zoukankan      html  css  js  c++  java
  • 算法 识别有效ip地址和掩码并做统计

    题目描述

    请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

    所有的IP地址划分为 A,B,C,D,E五类

    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

    私网IP范围是:

    10.0.0.0~10.255.255.255

    172.16.0.0~172.31.255.255

    192.168.0.0~192.168.255.255

     
    子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)

    输入描述:

    多行字符串。每行一个IP地址和掩码,用~隔开。

    输出描述:

    统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

    示例1

    输入

    复制
    10.70.44.68~255.254.255.0
    1.0.0.1~255.0.0.0
    192.168.0.2~255.255.255.0
    19..0.~255.255.255.0
    

    输出

    复制
    1 0 1 0 0 2 1

    参考讨论;子网掩码这块不是很熟悉,感觉没有特别好的算法,看起来都有点暴力

    链接:https://www.nowcoder.com/questionTerminal/de538edd6f7e4bc3a5689723a7435682?f=discussion
    来源:牛客网

    Yac836作者

    这个问题注意一下几点

    1. 255.255.255.255 为非法子网掩码(题目的意思,实际这个掩码,也能用)
    2. 当子网掩码错误时,不在判断ip是否有效,错误直接加一, 进行下次循环
    3. 当一个ip属于ABCDE类中的一个时候,也属于私有ip时,私有ip和他属于的分类都应该加一

    解题的方法

    1. 判断子网掩码是否有效

      1. 通过判断是否为255.255.255.255 如果是的话,错误加一,继续下次循环
      2. 判断别的子网掩码是否正确。根据子网掩码二进制规律(开头为连续的1,然后为0),我们将子网掩码按位取反,然后加一,得到的新二进制位,然后我们通过判断二进制中1的个数来判断是否为合法的子网掩码。(因为合法的子网掩码,按位取反,加一后,二进制位中,只有一个1)
        int validMask(char *p) {
        int flag,i ;
        unsigned int b1 = 0, n[4];
        sscanf(p, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);
        if(n[0] == 255 &&n[1] == 255 &&n[2] == 255 &&n[3] == 255 ) {
        flag = false;
        return flag;
        }
        for(i = 0; i < 4; ++i)
        b1 += n[i] << (i * 8);
        b1 = ~b1 + 1;
        if((b1 & (b1 - 1)) == 0) {
        flag = true;
        } else
        flag = false;
        return flag;
        }
    2. 判断ip时候有效,我们可以通过网络编程中自带的函数进行判断

      #include <arpa/inet.h>
      int inet_pton(int family, const char *strptr, void *addrptr);
                  返回:若成功则为1,若输入不是有效的表达格式则为0,若出错则为-1
    3. 如果ip地址有效,我们就可以判断它属于哪一类,是否是私有ip
    4. 完整代码


    #include <stdio.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #include <stdlib.h> #include <string.h> #define true 1 #define false 0 int validMask(char *p) { int flag,i ; unsigned int b1 = 0, n[4]; sscanf(p, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]); if(n[0] == 255 &&n[1] == 255 &&n[2] == 255 &&n[3] == 255 ) { flag = false; return flag; } for(i = 0; i < 4; ++i) b1 += n[i] << (i * 8); b1 = ~b1 + 1; if((b1 & (b1 - 1)) == 0) { flag = true; } else flag = false; return flag; } int main() { char str[50]; int a =0, b = 0, c = 0, d = 0, e = 0, err = 0, pri = 0; while(fgets(str,50,stdin)) { char *tok = str; char p[2][20] = {0}; int i = 0; while ((tok = strtok(tok, "~")) != NULL) { strcpy(p[i], tok); tok = NULL; i ++ ; if(i == 2) i = 0; } int flag = validMask(p[1]); if(flag) { struct in_addr s; unsigned int ip1,ip2; int valid = inet_pton(AF_INET,p[0],(void *)&s); sscanf(p[0],"%u.%u",&ip1,&ip2); if(valid) { if(ip1>=1 && ip1 <=126) a++; else if(ip1>=128 && ip1 <=191) b++; else if(ip1>=192 && ip1 <=223) c++; else if(ip1>=224 && ip1 <=239) d++; else if(ip1>=240 && ip1 <=255) e++; if(ip1==10 || (ip1==172 && ip2 >=16 &&ip2 <=31) || (ip1==192 && ip2 ==168)) pri ++; } else err ++; } else err++; } printf("%d %d %d %d %d %d %d ",a,b,c,d,e,err,pri); return 0; }

    C里面net去解,想法很不错,不熟悉仅做参考学习。
  • 相关阅读:
    学到的一些函数和好的方法
    MVC 捋一遍(3)
    MVC 捋一遍(2)
    mvc 安装ef遇到的各种奇葩问题
    MVC 捋一遍(1)
    httpServletRequest.getCharacterEncoding()取出来是个null,怎么办?
    spring常用注解
    覆盖io.spring.platform管理的版本号
    下拉点击跳到指定链接(类同友情链接)
    EditPlus 3.7激活码注册码
  • 原文地址:https://www.cnblogs.com/liuruoqian/p/11656571.html
Copyright © 2011-2022 走看看