算法 識別有效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\n",a,b,c,d,e,err,pri); return 0; }

C里面net去解,想法很不錯,不熟悉僅做參考學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM