判断两个IP是否属于同一子网
描述
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
示例:
IP 地址 192.168.0.1
子网掩码 255.255.255.0
转化为二进制进行运算:
IP 地址 11000000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000
AND运算 11000000.10101000.00000000.00000000
转化为十进制后为:192.168.0.0
IP 地址 192.168.0.254
子网掩码 255.255.255.0
转化为二进制进行运算:
IP 地址 11000000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000
AND运算 11000000.10101000.00000000.00000000
转化为十进制后为:192.168.0.0
通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0
,所以这二台计算机可视为是同一子网络。
输入一个子网掩码以及两个ip地址,判断这两个ip地址是否是一个子网络。
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2。
注:
有效掩码与IP的性质为:
- 掩码与IP每一段在 0 - 255 之间
- 掩码的二进制字符串前缀为网络号,都由‘1’组成;后缀为主机号,都由’0’组成
本题有多组输入
输入描述:
多组输入,一组3行,第1行是输入子网掩码、第2,3行是输入两个ip地址
输出描述:
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2
示例1
输入:
255.255.255.0
192.168.224.256
192.168.10.4
255.0.0.0
193.194.202.15
232.43.7.59
255.255.255.0
192.168.0.254
192.168.0.1
输出:
1
2
0
说明:
对于第一个例子:
255.255.255.0
192.168.224.256
192.168.10.4
//其中IP:192.168.224.256不合法,输出1
对于第二个例子:
255.0.0.0
193.194.202.15
232.43.7.59
///2个与运算之后,不在同一个子网,输出2
对于第三个例子,2个与运算之后,如题目描述所示,在同一个子网,输出0
答案优化前:
#include<iostream>
#include<string>
#include<sstream>
#include<vector>
using namespace std;
int main(){
string str;
while(cin>>str){
string str1,str2;
cin>>str1>>str2;
stringstream sstream1(str);
stringstream sstream2(str1);
stringstream sstream3(str2);
string token;
vector<int> vec1;
vector<int> vec2;
vector<int> vec3;
while(getline(sstream1,token,'.')){
vec1.push_back(atoi(token.c_str()));
}
while(getline(sstream2,token,'.')){
vec2.push_back(atoi(token.c_str()));
}
while(getline(sstream3,token,'.')){
vec3.push_back(atoi(token.c_str()));
}
if(vec1[0]==0 || vec1[3]==255 || vec1.size()!=4 || vec2.size()!=4 || vec3.size()!=4){
cout<<1<<endl;
continue;
}
bool flag= true;
for(int i=0;i<4 && flag;++i){
if(vec1[i]<0 || vec1[i]>255){
flag=false;
break;
}
if(vec1[i]==255) continue;
else{
if(vec1[i]!=254 && vec1[i]!=252 && vec1[i]!=248 && vec1[i]!=240
&& vec1[i]!=224 && vec1[i]!=192 && vec1[i]!=128 && vec1[i]!=0){
flag=false;
break;
}
for(int j=i+1;j<4;++j){
if(vec1[j]!=0){
flag=false;
break;
}
}
}
}
for(int i=0;i<4;++i){
if(vec2[i]<0 || vec2[i]>255 || vec3[i]<0 || vec3[i]>255){
flag=false;
break;
}
}
if(!flag){
cout<<1<<endl;
continue;
}
bool flag2=true;
for(int i=0;i<4;++i){
if((vec2[i] & vec1[i])!=(vec3[i] & vec1[i])){
cout<<2<<endl;
flag2=false;
break;
}
}
if(flag2){
cout<<0<<endl;
}
}
return 0;
}
优化输入:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> mask(4,0);
vector<int> ip1(4,0);
vector<int> ip2(4,0);
char c;
while (cin>>mask[0]>>c>>mask[1]>>c>>mask[2]>>c>>mask[3])//输入掩码
{
int flag = -1;//结果
cin>>ip1[0]>>c>>ip1[1]>>c>>ip1[2]>>c>>ip1[3];//第一个ip地址
cin>>ip2[0]>>c>>ip2[1]>>c>>ip2[2]>>c>>ip2[3];//第二个ip地址
for(int i=0;i<4;i++)//两个ip地址和掩码每一段都要在0-255之间
{
if(mask[i]<0 || mask[i]>255 || ip1[i]<0 || ip1[i]>255 ||ip2[i]<0 || ip2[i]>255)
{
flag = 1;//格式非法
break;
}
}
for(int i=0;i<3;i++)//掩码的网络号全为1,主机号全为0
{
if(mask[i]<255 && mask[i+1]>0)
{
flag = 1;
break;
}
}
if(flag==1)//格式非法,输出1
{
cout<<flag<<endl;
}else{
for(int i=0;i<4;i++)
{
if((mask[i]&ip1[i])!=(mask[i]&ip2[i]))//两个ip地址和掩码做AND操作
{
flag = 2;
break;
}else{//AND操作结果不相同
flag = 0;
}
}
cout<<flag<<endl;
}
}
return 0;
}