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

提示:文章

文章目录

前言

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


一、 代码:

第一版代码没有对掩码网络号进行处理。一开始对非法字段的理解就是value大于255。然后执行示例,

254.255.0.0

85.122.52.249

10.57.28.117

1

2

出现错误,增加修改为掩码只能是255和0这两个,跑了下面的代码,还是有示例没有通过。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    int a, b;
    char sonNet[20] = {'\0'};
    char ip1[20] = {'\0'};
    char ip2[20] = {'\0'};
    int arraySonNet[4] = {0};
    int arrayIp1[4] = {0};
    int arrayIp2[4] = {0};
    
    while (scanf("%s", sonNet) != EOF) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to 
        char output = 'f';
        char delimiters[2] = ".";
        char* p = strtok(sonNet, delimiters);
        int index = 0;
        while(p != NULL)
        {
            //printf("%s\n", p);
            int data = atoi(p);
            if(data > 255)
            {
                output = '1';
                break;
            }
            else if(data != 255 && data != 0)
            {
                output = '1';
                break;
            }
            arraySonNet[index++] = data;
            p = strtok(NULL, delimiters);
        }
        if(scanf("%s", ip1) != EOF)
        {
            p = strtok(ip1, delimiters);
            int index = 0;
            while(p != NULL)
            {
                //printf("%s\n", p);
                int data = atoi(p);
                if(data > 255)
                {
                    
                    output = '1';
                    break;
                }
                arrayIp1[index++] = data;
                p = strtok(NULL, delimiters);
            }
        }
        if(scanf("%s", ip2) != EOF)
        {
            p = strtok(ip2, delimiters);
            int index = 0;
            while(p != NULL)
            {
                //printf("%s\n", p);
                int data = atoi(p);
                if(data > 255)
                {
                    output = '1';
                    break;
                }
                arrayIp2[index++] = data;
                p = strtok(NULL, delimiters);
            }
        }
        int count = 0;
        for(int i = 0; i < 4; i++)
        {
            if( (ip1[i] & sonNet[i]) == (ip2[i] & sonNet[i]) )
            {
                ++count;
            }
        }
        if(output == 'f')
        {
            if(count == 4)
            {
                output = '0';
            }
            else {
                output = '2';
            }
        }
        
        
        printf("%c\n", output);
    }
    
    return 0;
}

255.255.252.0

173.225.245.45

69.138.93.228

2

1

这个示例没有通过。然后我仔细看了下题目对于掩码非法的说明。其中有这句话:掩码的二进制字符串前缀为网络号,都由'1'组成;后缀为主机号,都由'0'组成。

这边涉及到掩码的网络号的问题,还需要单独处理一下逻辑。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool isTargetSonNet(int array[], int len)
{
    int tempArray[32] = {0};
    int tempArrayIndex = 0;
    for(int i = 0; i < len; i++)
    {
        int data = array[i];
        if(data > 255)
        {
            return false;
        }
        int index = ((tempArrayIndex + 1) * 8);
        while(data)
        {
            int dat = data % 2;
            tempArray[--index] = dat;
            data /= 2;
        }
        tempArrayIndex++;
    }

    int count = 0;
    for(int i = 0; i < 32; i++)
    {
        int temp = tempArray[i] - tempArray[i + 1];
        if(temp == 1)
        {
            count++;
        }
    }

    if(count != 1)
    {
        return false;
    }

    return true;
}

int main() {
    int a, b;
    char sonNet[20] = {'\0'};
    char ip1[20] = {'\0'};
    char ip2[20] = {'\0'};
    int arraySonNet[4] = {0};
    int arrayIp1[4] = {0};
    int arrayIp2[4] = {0};
    
    while (scanf("%s", sonNet) != EOF) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to 
        char output = 'f';
        char delimiters[2] = ".";
        char* p = strtok(sonNet, delimiters);
        int index = 0;
        while(p != NULL)
        {
            //printf("%s\n", p);
            int data = atoi(p);
            
            // if(data > 255)
            // {
            //     output = '1';
            //     break;
            // }
            // else if(data != 255 && data != 0)
            // {
            //     output = '1';
            //     break;
            // }
            arraySonNet[index++] = data;
            p = strtok(NULL, delimiters);
        }
        if(!isTargetSonNet(arraySonNet, 4))
        {
            output = '1';
        }
        if(scanf("%s", ip1) != EOF)
        {
            p = strtok(ip1, delimiters);
            int index = 0;
            while(p != NULL)
            {
                //printf("%s\n", p);
                int data = atoi(p);
                if(data > 255)
                {
                    
                    output = '1';
                    break;
                }
                arrayIp1[index++] = data;
                p = strtok(NULL, delimiters);
            }
        }
        if(scanf("%s", ip2) != EOF)
        {
            p = strtok(ip2, delimiters);
            int index = 0;
            while(p != NULL)
            {
                //printf("%s\n", p);
                int data = atoi(p);
                if(data > 255)
                {
                    output = '1';
                    break;
                }
                arrayIp2[index++] = data;
                p = strtok(NULL, delimiters);
            }
        }
        int count = 0;
        for(int i = 0; i < 4; i++)
        {
            if( (ip1[i] & sonNet[i]) == (ip2[i] & sonNet[i]) )
            {
                ++count;
            }
        }
        if(output == 'f')
        {
            if(count == 4)
            {
                output = '0';
            }
            else {
                output = '2';
            }
        }
        
        
        printf("%c\n", output);
    }
    
    return 0;
}

以为上面的版本会通过,不过下面的示例还是没有通过

cpp 复制代码
1.255.255.0
187.39.235.7
219.79.189.231
1
2

增加对isTargetStr函数的逻辑处理

cpp 复制代码
bool isTargetSonNet(int array[], int len)
{
    int tempArray[32] = {0};
    int tempArrayIndex = 0;
    for(int i = 0; i < len; i++)
    {
        int data = array[i];
        if(data > 255)
        {
            return false;
        }
        int index = ((tempArrayIndex + 1) * 8);
        while(data)
        {
            int dat = data % 2;
            tempArray[--index] = dat;
            data /= 2;
        }
        tempArrayIndex++;
    }

    int count = 0;
    for(int i = 0; i < 32; i++)
    {
        int temp = tempArray[i] - tempArray[i + 1];
        if(temp != 0 && temp != 1)
        {
            return false;
        }
        if(temp == 1)
        {
            count++;
        }
    }

    if(count != 1)
    {
        return false;
    }

    return true;
}

还是没有通过全部示例

255.0.0.0

193.194.202.15

232.43.7.59

2

1

修改isTargetStr函数如下

cpp 复制代码
bool isTargetSonNet(int array[], int len)
{
    int tempArray[32] = {0};
    int tempArrayIndex = 0;
    for(int i = 0; i < len; i++)
    {
        int data = array[i];
        if(data > 255)
        {
            return false;
        }
        int index = ((tempArrayIndex + 1) * 8);
        while(data)
        {
            int dat = data % 2;
            tempArray[--index] = dat;
            data /= 2;
        }
        tempArrayIndex++;
    }

    int count = 0;
    for(int i = 0; i + 1 < 32; i++)
    {
        int temp = tempArray[i] - tempArray[i + 1];
        if(temp != 0 && temp != 1)
        {
            return false;
        }
        if(temp == 1)
        {
            count++;
        }
    }

    if(count != 1)
    {
        return false;
    }

    return true;
}

主要是这一行: for(int i = 0; i + 1 < 32; i++)

修改后示例报错

255.255.255.0

167.-79.164.247

158.201.137.151

1

2

将isTragetStr函数改成下述形式

cpp 复制代码
bool isTargetSonNet(int array[], int len)
{
    int tempArray[32] = {0};
    int tempArrayIndex = 0;
    for(int i = 0; i < len; i++)
    {
        int data = array[i];
        if(data > 255 || data < 0)
        {
            return false;
        }
        int index = ((tempArrayIndex + 1) * 8);
        while(data)
        {
            int dat = data % 2;
            tempArray[--index] = dat;
            data /= 2;
        }
        tempArrayIndex++;
    }

    int count = 0;
    for(int i = 0; i + 1 < 32; i++)
    {
        int temp = tempArray[i] - tempArray[i + 1];
        if(temp != 0 && temp != 1)
        {
            return false;
        }
        if(temp == 1)
        {
            count++;
        }
    }

    if(count != 1)
    {
        return false;
    }

    return true;
}

试了下还是不行,我才意识到可能是因为atoi的原因。

我用的atoi函数,可以转成有符号数吗?这边要处理一下。

2、总结

接下文:HJ39判断两个IP是否属于同一子网(中)

相关推荐
GZ_TOGOGO35 分钟前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
小鹿( ﹡ˆoˆ﹡ )43 分钟前
探索IP协议的神秘面纱:Python中的网络通信
python·tcp/ip·php
三金121381 小时前
SpringIoC容器的初识
网络·网络协议·rpc
XKSYA(小巢校长)2 小时前
NatGo我的世界联机篇
开发语言·php
SizeTheMoment3 小时前
初识HTTP协议
网络·网络协议·http
lxp1997413 小时前
php函数积累
开发语言·php
5967851544 小时前
DotNetty ChannelRead接收数据为null
tcp/ip·c#
hgdlip5 小时前
如何快速切换电脑的ip地址
网络·tcp/ip·电脑
ac-er88885 小时前
PHP“===”的意义
开发语言·php
wxin_VXbishe5 小时前
springboot合肥师范学院实习实训管理系统-计算机毕业设计源码31290
java·spring boot·python·spring·servlet·django·php