识别有效的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就是一个非法的掩码)
(注意二进制下全是1或者全是0均为非法子网掩码)
注意:
- 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
- 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。
输出描述:
统计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
复制
说明:
10.70.44.68255.254.255.0的子网掩码非法,19…0.255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
所以最终的结果为1 0 1 0 0 2 1
示例2
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255
复制
输出:
0 0 0 0 0 0 0
复制
说明:
类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
题目里面陷阱很多,需要搞清楚。
暴力法:
#include <iostream>
#include <string>
using namespace::std;
typedef struct {
int32_t first;
int32_t second;
int32_t third;
int32_t fourth;
}IP_int;
typedef struct {
int ANumber;
int BNumber;
int CNumber;
int DNumber;
int ENumber;
int errIPNumber;
int priIPNumber;
}res_t;
static int processInput(string s, IP_int *IP, IP_int *mask) {
int flage = 0;
for (int i = 0 ; i < s.length(); ) {
if (!flage) {
string first;
while (i < s.length() && s[i]!='.' && s[i]!='~') {
first += s[i];
i++;
}
if(first!="") IP->first = stoi(first);
i++;
if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
string second;
while (i < s.length() && s[i]!='.' && s[i]!='~') {
second += s[i];
i++;
}
if(second!="") IP->second = stoi(second);
if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
i++;
string third;
while (i < s.length() && s[i]!='.' && s[i]!='~') {
third += s[i];
i++;
}
if(third!="") IP->third = stoi(third);
if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
i++;
string fourth;
while (i < s.length() && s[i]!='.' && s[i]!='~') {
fourth += s[i];
i++;
}
if(fourth!="") IP->fourth = stoi(fourth);
if (i < s.length() && s[i]=='~') { flage = 1; i++; continue; };
i++;
} else {
string first;
while (i < s.length() && s[i] != '.' && s[i] != '\0') {
first += s[i];
i++;
}
if(first!="") mask->first = stoi(first);
if (i < s.length() && s[i] == '\0') break;
i++;
string second;
while (i < s.length() && s[i] != '.' && s[i] != '\0') {
second += s[i];
i++;
}
if(second!="") mask->second = stoi(second);
if (i < s.length() && s[i] == '\0') break;
i++;
string third;
while (i < s.length() && s[i] != '.' && s[i] != '\0') {
third += s[i];
i++;
}
if(third!="") mask->third = stoi(third);
if (i < s.length() && s[i] == '\0') break;
i++;
string fourth;
while (i < s.length() && s[i] != '.' && s[i] != '\0') {
fourth += s[i];
i++;
}
if(fourth!="") mask->fourth = stoi(fourth);
if (i < s.length() && s[i] == '\0') break;
i++;
}
if (i < s.length() && s[i]=='~') flage = 1;
i++;
}
return 0;
}
#define CAL_ERR (0)
#define MASK_RIGHT (1)
#define CAL_RIGHT MASK_RIGHT
void dec2binary(int num, uint8_t *mask_binary)
{
int t = num;
for(int i=0; i<8; i++)
{
mask_binary[i] = t & 1;
t = t>>1;
}
}
static int cal_Mask(IP_int *mask_input) {
if (mask_input->first < 0 || mask_input->first > 255) return CAL_ERR;
if (mask_input->second < 0 || mask_input->second > 255) return CAL_ERR;
if (mask_input->third < 0 || mask_input->third > 255) return CAL_ERR;
if (mask_input->fourth < 0 || mask_input->fourth > 255) return CAL_ERR;
uint8_t s[32] = {0};
int index = 31;
uint8_t mask_binary[8] = {0};
dec2binary(mask_input->first, mask_binary);
for (int i = 7; i >= 0; i--) {
s[index--] = mask_binary[i];
}
dec2binary(mask_input->second, mask_binary);
for (int i = 7; i >= 0; i--) {
s[index--] = mask_binary[i];
}
dec2binary(mask_input->third, mask_binary);
for (int i = 7; i >= 0; i--) {
s[index--] = mask_binary[i];
}
dec2binary(mask_input->fourth, mask_binary);
for (int i = 7; i >= 0; i--) {
s[index--] = mask_binary[i];
}
int left = 31;
int right = 0;
while (left >= 0 && s[left] == 1) left--;
while (right < 32 && s[right] == 0) right++;
if (left < 0 || right > 31) return CAL_ERR;
if ((left < right)) {
return MASK_RIGHT;
}
// if (left > right){
// return CAL_ERR;
// }
// if (left == right){
// return MASK_RIGHT;
// }
return CAL_ERR;
}
static int IP_il(IP_int *IP_input){
if (IP_input->first < 0 || IP_input->first > 255 ) {
//res->errIPNumber++;
return CAL_ERR;
}
if (IP_input->second < 0 || IP_input->second > 255) {
//res->errIPNumber++;
return CAL_ERR;
}
if (IP_input->third < 0 || IP_input->third > 255) {
//res->errIPNumber++;
return CAL_ERR;
}
if (IP_input->fourth < 0 || IP_input->fourth > 255) {
//res->errIPNumber++;
return CAL_ERR;
}
return CAL_RIGHT;
}
static int cal_IP(IP_int *IP_input, res_t *res, int pre) {
if ((IP_input->first >= 1) && (IP_input->first <= 126)) {
if (pre == MASK_RIGHT) res->ANumber++;
if (IP_input->first == 10) res->priIPNumber++;
return CAL_RIGHT;
}
else if ((IP_input->first >= 128) && (IP_input->first <= 191)) {
if (pre == MASK_RIGHT) res->BNumber++;
if ( IP_input->first == 172 && IP_input->second >= 16 && IP_input->second <= 31) res->priIPNumber++;
return CAL_RIGHT;
}
else if ((IP_input->first >= 192) && (IP_input->first <= 223)) {
if (pre == MASK_RIGHT) res->CNumber++;
if (IP_input->first == 192 && IP_input->second == 168) res->priIPNumber++;
return CAL_RIGHT;
}
else if ((IP_input->first >= 224) && (IP_input->first <= 239)) {
if(pre == MASK_RIGHT) res->DNumber++;
return CAL_RIGHT;
}
else if ((IP_input->first >= 240) && (IP_input->first <= 255)) {
if(pre == MASK_RIGHT) res->ENumber++;
return CAL_RIGHT;
}
//if(pre == MASK_RIGHT) res->errIPNumber++;
return CAL_RIGHT;
}
static void cal_number(IP_int *IP_input, IP_int *mask_input, res_t *res) {
int t = cal_Mask(mask_input);
// if (t == 0) res->errIPNumber++;
if (IP_input->first == 127) return;//|| mask_input->fourth == 0xffffffff
int ti = IP_il(IP_input);
if (ti == CAL_ERR && t == CAL_ERR) return;
if (ti == CAL_ERR || t == CAL_ERR) {
res->errIPNumber++;
return;
}
if (ti == CAL_RIGHT && t == CAL_RIGHT) cal_IP(IP_input,res,t);
return ;
}
int main(){
string input;
res_t res = {0};
while(cin>>input){
IP_int IP = {256,256,256,256};
IP_int mask = {256,256,256,256};
processInput(input, &IP, &mask);
// cout<<IP.first<<" "<<IP.second<<" "<<IP.third<<" "<<IP.fourth<<endl;
// cout<<mask.first<<" "<<mask.second<<" "<<mask.third<<" "<<mask.fourth<<endl;
cal_number(&IP, &mask, &res);
}
cout<<res.ANumber<<" "<<res.BNumber<<" "<<res.CNumber<<" "<<res.DNumber<<" "<<res.ENumber
<<" "<<res.errIPNumber<<" "<<res.priIPNumber<<endl;
return 0;
}