#include <stdio.h> #include <string.h> int ip_islegal(int ip[], int n); int dns_islegal(int dns[], int n); int main() { char buf[500]; int A = 0, B = 0, C = 0, D = 0, E = 0, Priv = 0, Err = 0; int ip[4]; int dns[4]; //读取ip地址和子网掩码地址 while(scanf("%s", buf) != EOF) { memset(ip, 0, 4*sizeof(int)); memset(dns, 0, 4*sizeof(int)); sscanf(buf, "%d.%d.%d.%d~%d.%d.%d.%d", &ip[0],&ip[1],&ip[2],&ip[3],&dns[0],&dns[1],&dns[2],&dns[3]); //"0.*.*.*" 和 "127.*.*.*""127.*.*.*" 的 IP 地址不计入任何类别,直接跳过; if((ip[0]==0) || (ip[0]==127)) { continue; } //非法ip地址和非法子网掩码地址统计 if((!ip_islegal(ip, 4)) || (!dns_islegal(dns, 4))) { Err++; } //合法ip地址和合法子网掩码地址统计 //A/B/C/D/E/Priv_ip else { if(ip[0] >= 1 && ip[0] <= 127) A++; else if(ip[0] >= 128 && ip[0] <= 191) B++; else if(ip[0]>=192 && ip[0]<=223) C++; else if(ip[0]>=224 && ip[0]<=239) D++; else if(ip[0]>=240 && ip[0]<=255) E++; //统计私有地址 if(ip[0]==10) { Priv++; } else if(ip[0]==172) { if(ip[1]>=16 && ip[1]<=31) { Priv++; } } else if(ip[0]== 192) { if(ip[1] == 168) Priv++; } } } printf("%d %d %d %d %d %d %d", A, B, C, D, E, Err, Priv); return 0; } //判断ip地址是否合法 int ip_islegal(int ip[], int n) { //假设ip地址合法 int ret = 1; int i; for(i = 0; i < n; i++) { if((ip[i] < 0) || (ip[i] > 255)) { ret = 0; break; } } return ret; } //判断子网掩码地址是否合法 int dns_islegal(int dns[], int n) { int i; //统计255的个数 int count = 0; //假设子网掩码合法 int ret = 1; //标记是否已遇到第一个非255地址段 int flag = 0; int legal[9] = {0}; //判断第一个地址段是否为255 if(dns[0] != 255) { ret = 0; return ret; } //遍历地址段 for(i = 0; (ret==1)&&(i<n); i++) { //阶段一:统计255的个数 if((flag==0) && (dns[i]==255)) { count++; } //阶段二:遇到第一个非255的地址段 //验证地址是否合法 else if(flag == 0) { flag++; //假设子网掩码地址是非法的 ret = 0; //预计算合法的掩码地址(128,192,224,240,248,252,254,255) for(int m=128,k=1; m>=1; m /= 2, k++) { legal[k] = legal[k-1]+m; } //检查当前地址段是否为合法掩码值 for(int j = 0; j < 9; j++) { if(dns[i] == legal[j]) { ret = 1; break; } } } //阶段三:验证后续地址段是否全为0 else { if(dns[i] != 0) { ret = 0; break; } } } //检验地址段是否全是255(则为非法地址) if(count==4) { ret = 0; } return ret; }