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是否属于同一子网(中)

相关推荐
字节全栈_rJF3 小时前
概述、 BGP AS 、BGP 邻居、 BGP 更新源 、BGP TTL 、BGP路由表、 BGP 同步
网络·智能路由器·php
m0_465215795 小时前
TCP & UDP Service Model
服务器·网络·tcp/ip
esmember5 小时前
电路研究9.2.6——合宙Air780EP中HTTP——HTTP GET 相关命令使用方法研究
网络·网络协议·http·at指令
dal118网工任子仪5 小时前
92,[8] 攻防世界 web Web_php_wrong_nginx_config
开发语言·php
aaaweiaaaaaa7 小时前
php的使用及 phpstorm环境部署
android·web安全·网络安全·php·storm
weisian1518 小时前
消息队列篇--通信协议篇--STOMP(STOMP特点、格式及示例,WebSocket上使用STOMP,消息队列上使用STOMP等)
websocket·网络协议
jax不摆烂10 小时前
浅谈TCP/IP
网络·tcp/ip
追风赶月、11 小时前
【网络】传输层协议UDP
网络·网络协议·udp
霸王蟹11 小时前
http和https的区别?
网络·笔记·网络协议·学习·http·https
精通HelloWorld!11 小时前
使用HttpClient和HttpRequest发送HTTP请求
java·spring boot·网络协议·spring·http