判断两个IP是否属于同一子网

判断两个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的性质为:

  1. 掩码与IP每一段在 0 - 255 之间
  2. 掩码的二进制字符串前缀为网络号,都由‘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;
}
  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值