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

相关推荐
诗句藏于尽头6 小时前
完成ssl不安全警告
网络协议·安全·ssl
浪裡遊9 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
会飞的鱼先生9 小时前
Node.js-http模块
网络协议·http·node.js
-qOVOp-13 小时前
408第三季part2 - 计算机网络 - ip分布首部格式与分片
网络协议·tcp/ip·计算机网络
数通Dinner13 小时前
RSTP 拓扑收敛机制
网络·网络协议·tcp/ip·算法·信息与通信
ejinxian16 小时前
PHP 超文本预处理器 发布 8.5 版本
开发语言·php
zorro_z17 小时前
PHP语法基础篇(九):正则表达式
php
qq_1715388520 小时前
TCP/IP协议精解:IP协议——互联网世界的邮政编码系统
网络·网络协议·tcp/ip
珹洺20 小时前
计算机网络:(七)网络层(上)网络层中重要的概念与网际协议 IP
网络·tcp/ip·计算机网络
兮动人21 小时前
获取终端外网IP地址
java·网络·网络协议·tcp/ip·获取终端外网ip地址