题目:找出n个IP中的黑名单IP
黑名单定义:给定了m个IP,mask采用CIDR表示,网段相同则判定为黑名单
example:
illegal_ip_01: 192.168.254.121/24
illegal_ip_02: 116.7.221.23/16
test_ip_01: 192.168.254.11
test_ip_02: 116.7.222.1
上述给定的两个test IP均不合法。
下面提供了c++解法
注:批量IP检查可以直接调用下面接口暴力循环,也可以先将所有的不合法IP转换为二进制保存到数组,然后再依次遍历,可以节约不少时间。
bool judgeLegelIp(string mask,string test){
//将字符串转换为两个32位无符号整型进行比较
uint32_t mask_bit=0;
int i=0, k=3;
while(i< mask.size()){
string tempStr;
while(mask[i]!='.'&&mask[i]!='/'){
tempStr+=mask[i++];
}
uint32_t b(stoi(tempStr)<<(k--)*8);
mask_bit |= b;
if(mask[i]=='/')
break;
++i;
}
++i;
string temps;
while(i<mask.size()){
temps+=mask[i++];
}
uint32_t mask_bitcnt(stoi(temps));//记录掩码位数
uint32_t test_bit=0;
int j=0,m=3;
while(j<test.size()){
string s1;
while(j<test.size()&&test[j]!='.'){
s1+=test[j++];
}
uint32_t b(stoi(s1)<<(m--)*8);
test_bit |= b;
++j;
}
mask_bit>>=(32-mask_bitcnt);
test_bit>>=(32-mask_bitcnt);
return (mask_bit^test_bit);
}
//test example
int main(){
string s1("192.168.254.11/24");
string s2("192.168.254.221");
string s3("192.168.221.1");
if(judgeLegelIp(s1,s2))
cout<<"legel IP"<<endl;
else
cout<<"illegel IP";
return 0;
}
完整优化版本:
#include <iostream>
#include <vector>
#include <string>
#include <sstream> //stringstream
using namespace std;
//c++实现split函数功能
vector<string> split(string s, char c){
stringstream ss(s);
vector<string> ans;
string tmpStr;
while(getline(ss,tmpStr,c)){
if(!tmpStr.empty()){
ans.push_back(tmpStr);
}
}
return ans;
}
uint32_t testip_to_num(string s){
vector<string> res2 = split(s,'.');
uint32_t ip_num = 0;
int k =3;
for(int i = 0; i < 4; ++i){
ip_num |= (stoi(res2[i]) << 8*(k--));
}
return ip_num;
}
pair<uint32_t, int> maskip_to_num(string s){
pair<uint32_t, int>ans;
vector<string> res1 = split(s,'/');
string s1 = res1.front();
vector<string> res2 = split(s1,'.');
uint32_t ip_num = 0;
int k =3;
for(int i = 0; i < 4; ++i){
ip_num |= (stoi(res2[i]) << 8*(k--));
}
int bit_str = stoi(res1.back());
ans = make_pair(ip_num, bit_str);
return ans;
}
bool is_black_ip(string maskip, string test_ip){
pair<uint32_t, int> pp = maskip_to_num(maskip);
uint32_t testip = testip_to_num(test_ip);
if((testip >> (32 - pp.second)) == (pp.first >> (32 - pp.second))){
return true;
}
return false;
}
int main (){
int m,n;
cin>>m>>n;
string mask;
string test;
vector<string>v1(m),v2(n);
int i = 0, j = 0;
while(cin>>v1[i++], i < m);
while(cin>>v2[j++], j < n);
//output black ip
for(auto s2 : v2){
for(auto s1 : v1){
if(is_black_ip(s1,s2)){
cout<<s2<<endl;
}
}
}
return 0;
}
/*
//test example
2 4
121.121.121.28/24
113.121.121.23/20
121.121.121.121
113.121.116.198
113.121.144.2
224.121.121.112
*/