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

相关推荐
ServBay12 小时前
告别面条代码,PSL 5.0 重构 PHP 性能与安全天花板
后端·php
Qinana18 小时前
从数据包旅程到首屏渲染:深入理解 TCP/IP 如何决定你的 Web 性能
前端·tcp/ip·浏览器
Sheffield2 天前
Docker的跨主机服务与其对应的优缺点
linux·网络协议·docker
JaguarJack3 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo3 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack4 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo4 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack4 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay5 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954486 天前
CTF 伪协议
php