首页 > 试题广场 >

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

[编程题]判断两个IP是否属于同一子网
  • 热度指数:160922 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
IP地址是由4个0-255之间的整数构成的,用"."符号相连。
二进制的IP地址格式有32位,例如:10000011,01101011,00000011,00011000;每八位用十进制表示就是131.107.3.24
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,由1和0组成,且1和0分别连续,其中网络号部分全为“1”和主机号部分全为“0”。
你可以简单的认为子网掩码是一串连续的1和一串连续的0拼接而成的32位二进制数,左边部分都是1,右边部分都是0。
利用子网掩码可以判断两台主机是否在同一子网中。
若两台主机的IP地址分别与它们的子网掩码进行逻辑“与”运算(按位与/AND)后的结果相同,则说明这两台主机在同一子网中。


示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址   11000000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000

AND运算   11000000.10101000.00000000.00000000

转化为十进制后为:
192.168.0.0


I P 地址  192.168.0.254
子网掩码  255.255.255.0


转化为二进制进行运算:

I P 地址 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地址
题目的示例中给出了三组数据,但是在实际提交时,你的程序可以只处理一组数据(3行)。



输出描述:

若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 <stdio.h>

typedef struct ip{
    int error;
    int same;
    int diff;
} IP;

int main() {
    int ip1[4];
    int ip2[4];
    int mask[4];
    char str[200];
    IP ip={0};
    while (scanf("%d.%d.%d.%d\r\n%d.%d.%d.%d\r\n%d.%d.%d.%d",
        &mask[0], &mask[1], &mask[2], &mask[3],
        &ip1[0], &ip1[1], &ip1[2], &ip1[3],
        &ip2[0], &ip2[1], &ip2[2], &ip2[3]) != EOF) { 
        
    
    //判断ip或者掩码非法;
    if ((ip1[0]<0)|| (ip1[0]>255) || (ip1[1]<0)|| (ip1[1]>255) || (ip1[2]<0)|| (ip1[2]>255) ||
     (ip1[3]<0)|| (ip1[3]>255) || (ip2[0]<0)|| (ip2[0]>255) || (ip2[1]<0)|| (ip2[1]>255) || (ip2[2]<0)|| (ip2[2]>255) ||
     (ip2[3]<0)|| (ip2[3]>255)) {
        
        ip.error=1;
        continue;
    }
    int mask32 = (mask[0] << 24)+(mask[1] << 16)+(mask[2] << 8)+mask[3];
    if(((~mask32+1)&(~mask32)) || !~mask32){
        
        ip.error=1;
        continue;
    }
    //判断是否在同一子网;
    int ip1_32 = (ip1[0] << 24)+(ip1[1] << 16)+(ip1[2] << 8)+ ip1[3];
    int ip2_32 = (ip2[0] << 24)+(ip2[1] << 16)+(ip2[2] << 8)+ ip2[3];
    if( (ip1_32&mask32) == (ip2_32&mask32)){
        ip.same=0;
    }
    else {
        ip.diff=2;
    }
    }
    printf("%d\n%d\n%d",ip.error,ip.diff,ip.same);
    return 0;
}

发表于 2024-09-03 11:06:54 回复(1)
#include <stdio.h>
#include <string.h>
#include <math.h>

typedef struct {
    int a[4];
    char str[4][9];
} thrity_nine_s;

int BinaryToDemical(char str[]) {
    int length = strlen(str);
    int ten = 0;
    for (int i = 0; i < length; i++) {
        if (str[i] == '1') {
            ten = ten + pow(2, 7 - i);
        }
    }
    return ten;
}

int maskValue(int a0, int a1, int a2, int a3) {
    int a[4];
    a[0] = a0;
    a[1] = a1;
    a[2] = a2;
    a[3] = a3;

    for (int i = 0; i < 4; i++) {
        if ((a[i] < 0) || (a[i] > 255)) {
            return 1;
        }
    }
    return 0;
}

int main() {
    thrity_nine_s tnt[3];
    thrity_nine_s ip[2];
    char c;
    for (int i = 0; i < 3; i++) {
        scanf("%d%c%d%c%d%c%d", &(tnt[i].a[0]), &c, &(tnt[i].a[1]), &c, &(tnt[i].a[2]),
              &c, &(tnt[i].a[3]));
    }

    int tt = 0;
    char m[33];

    for (int i = 0; i < 3; i++) {
        if (maskValue(tnt[i].a[0], tnt[i].a[1], tnt[i].a[2], tnt[i].a[3])) {
            printf("1");
            return 0;
        }
        for (int j = 0; j < 4; j++) {
            for (int k = 7; k >= 0; k--) {
                if (tnt[i].a[j] > 0) {
                    tnt[i].str[j][k] = '0' + tnt[i].a[j] % 2;
                    tnt[i].a[j] = tnt[i].a[j] / 2;
                } else {
                    tnt[i].str[j][k] = '0';
                }
            }
            tnt[i].str[j][8] = '\0';
            if (i == 0) {
                for (int k = 0; k < 8; k++) {
                    m[tt] = tnt[i].str[j][k];
                    tt++;
                }
            }
            m[32] = '\0';
        }
    }
    int count = 0;
    for (int i = 1; i < 32; i++) {
        if (m[i - 1] != m[i]) {
            count++;
            //printf("%d %d\n", i , count);
        }
    }
    if (count > 1) {
        printf("1");
        return 0;
    }
    for (int f = 0; f < 2; f++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k < 8; k++) {
                ip[f].str[i][k] = tnt[0].str[i][k] & tnt[f + 1].str[i][k];
            }
            ip[f].str[i][8] = '\0';
        }
    }

    for (int f = 0; f < 2; f++) {
        for (int i = 0; i < 4; i++) {
            ip[f].a[i] = BinaryToDemical(ip[f].str[i]);
        }
    }

    for (int i = 0; i < 4; i++) {
        if (ip[0].a[i] != ip[1].a[i]) {
            printf("2");
            return 0;
        }
    }

    printf("0");

    return 0;
}
发表于 2024-06-02 17:25:17 回复(0)
#include <stdio.h>

int isValidMask(unsigned int* mask) {
    unsigned int temp = 0;
    
    for(int i=0;i<4;i++){
        if(mask[i] > 255){
            return -1;
        }
    }

    temp = ((mask[0] & 0xff) << 24) | ((mask[1] & 0xff) << 16) |
    ((mask[2] & 0xff) << 8) | (mask[3] & 0xff);
    //10000000 00000000 00000000 00000000 
    while(temp & (0x01 << 31)){
        temp <<= 1;
    }

    if(temp){
        return -1;
    }

    return 0;
}

int isValidIp(unsigned int* ip) {
    for(int i=0;i<4;i++){
        if(ip[i] > 255){
            return -1;
        }
    }
    return 0;
}

int isMatchSubNet(unsigned int *mask, unsigned int *ip1, unsigned int *ip2)
{
    for(int i=0; i < 4; i++){
        if((ip1[i] & mask[i]) != (ip2[i] & mask[i])){
            return -1;
        }
    }
    return 0;
}

int main() {
    unsigned int mask[4] = {0};
    unsigned int ip1[4] = {0};
    unsigned int ip2[4] = {0};

    int ret;
    ret = scanf("%u.%u.%u.%u", &mask[0], &mask[1], &mask[2], &mask[3]);
    if (4 != ret) {
        goto error;
    }

    if (0 != isValidMask(mask)) {
        goto error;
    }

    ret = scanf("%u.%u.%u.%u", &ip1[0], &ip1[1], &ip1[2], &ip1[3]);
    if (4 != ret) {
        goto error;
    }

    if (0 != isValidIp(ip1)) {
        goto error;
    }

    ret = scanf("%u.%u.%u.%u", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
    if (4 != ret) {
        goto error;
    }

    if (0 != isValidIp(ip2)) {
        goto error;
    }

    if(0 != isMatchSubNet(mask, ip1, ip2)){
        printf("2\n");
    }else {
        printf("0\n");
    }
    
    return 0;

error:
    printf("1\n");

    return 0;
}

发表于 2024-02-20 10:14:51 回复(0)
#include <stdio.h>

int main(void)
{
  int ip1[4], ip2[4], mask[4];
  unsigned int i, ret, mask_reserve, mask_flag, mask_value;
  
  while(scanf("%d.%d.%d.%d\r\n%d.%d.%d.%d\r\n%d.%d.%d.%d",
        &mask[0], &mask[1], &mask[2], &mask[3],
        &ip1[0], &ip1[1], &ip1[2], &ip1[3],
        &ip2[0], &ip2[1], &ip2[2], &ip2[3]) != EOF)
  {    
    ret = 0;
    mask_value = 0;
     
    for(i = 0; i < 4; i++)
    {
      if((ip1[i] < 0 || ip1[i] > 255)
        || (ip2[i] < 0 || ip2[i] > 255)
        || (mask[i] < 0 || mask[i] > 255))
      {
        ret = 1;
        break;
      }
      mask_value = (mask_value << 0x08) | mask[i];
    }
    
    mask_flag = 0;
    mask_reserve = 0;
    if(ret == 0)
    {
      for(i = 0; i < 32; i++)
      {
        if(((mask_value >> i) & 0x01) != mask_reserve)
        {
          if(mask_flag)
          {
            ret = 1;
            break;;
          }
          else
          {
            mask_flag = 1;
            mask_reserve = 1;
          }
        }
      }
    }
    
    if(ret == 0)
    {
      for(i = 0; i < 4; i++)
      {
        ip1[i] &= mask[i];
        ip2[i] &= mask[i];
        if(ip1[i] != ip2[i])
        {
          ret = 2;
          break;
        }
      }
    }
    
    printf("%d\r\n", ret);
  }
}

发表于 2022-08-16 17:09:09 回复(0)
255.255.252.0
173.225.245.45
69.138.93.228
这个网络掩码明明是错的,为什么还是2
发表于 2022-05-28 16:48:36 回复(1)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int iPtoInt(char *ptrIp, int iLen, unsigned int *ptr_ip_mac)
{
	if(strstr(ptrIp, (const char*)"..") != NULL )
	{
		return 0;
	}
	
	int k = 0, i = 0, j = 0;
	char arr[4][4] = {0};
	
	char *ptrtempIp = ptrIp;
	
	for(k = 0; k < iLen; k++)
	{
		if(i >= 4 || j >= 4)
		{
			return 0;
		}
		
		if(*ptrtempIp == '.')
		{
			ptrtempIp++;
			i++;
			j = 0;
			continue;
		}else{
			arr[i][j++] = *ptrtempIp;
			ptrtempIp++;
		}
	}
	
	if(i != 3)
	{
		return 0;
	}
	
	for(i = 0; i < 4; i++)
	{
		if(atoi(arr[i]) < 0 || atoi(arr[i]) > 255)
		{
			return 0;
		}
		
		unsigned int uiTemp = 0x000000FF;
		
		uiTemp &= atoi(arr[i]);
		
		*ptr_ip_mac |= (uiTemp << (24 - (8 * i)));
	}
	
	return 1;
}

int judugeIsMack(unsigned int uiMack)
{
	int i = 0, itage = 0;
	
	for(i = 0; i < 32; i++)
	{
		if((uiMack & 0x00000001) == 0x00000000)
		{
			if(itage == 1)
			{
				return 0;
			}
		}else{
			itage = 1;
		}
		
		uiMack = (uiMack >> 1);
	}
	
	return 1;
}

int main()
{
	char str[64] = {0};
	
	while(scanf("%s", str) != EOF)
	{
		unsigned int uiIp1 = 0x00000000, uiIp2 = 0x00000000, uiMask = 0x00000000;
		char str_ip1[32] = {0}, str_ip2[32] = {0};
		
		scanf("%s", str_ip1);
		scanf("%s", str_ip2);
		
		if(iPtoInt(str, strlen(str), &uiMask) == 0 || judugeIsMack(uiMask) == 0)
		{
			printf("1\n");
			continue;
		}
		
		if(iPtoInt(str_ip1, strlen(str_ip1), &uiIp1) != 1 || iPtoInt(str_ip2, strlen(str_ip2), &uiIp2) != 1)
		{
			printf("1\n");
			continue;
		}
		
		if((uiMask & uiIp1) == (uiMask & uiIp2))
		{
			printf("0\n");
		}else{
			printf("2\n");
		}
	}
	
	return 0;
}

发表于 2021-12-08 14:53:53 回复(0)
子网掩码的合法性使用 0x01进行按位异或
发表于 2021-11-27 22:05:16 回复(0)
#include <stdio.h>
#include <string.h>

#define MASK  1
#define IP    0

unsigned int arr2int (unsigned char *arr, int arrLen)
{
    unsigned long temp = 0 ;
    for(int i = 0; i < arrLen; i++)
    {
        temp <<=8;
        temp  |= arr[i];
    }
    return temp;
}


//合法性检查
int is_legal( char *ip, int is_mask)
{
    unsigned char buf[4] = {0};
    int j = 0;
    
    unsigned char arry_temp[32] = {0};
    strcpy(arry_temp, ip);
    char *temp = NULL;
    temp = strtok(arry_temp, ".");
    
    while(temp !=NULL)
    {
        if( atoi(temp) > 255 || atoi(temp) <0)
             return 1;
        buf[j] = atoi(temp); 
        j++;
       temp = strtok(NULL, ".");
    }
    
    if(is_mask == MASK)
    {
       unsigned int max_mask = 0xffffffff;
        while(( max_mask  <<= 1) > 0 )
        {
            if(arr2int (buf, 4)  ==  max_mask)
                return 0;
        } 
       return 1;
    }
     
    return 0;
}

//转为unsigned char
unsigned char * str2arr(char  *str, unsigned char * result)
{
    int j = 0;
    unsigned char arry_temp[32] = {0};
    
    strncpy(arry_temp, str, 32);
    char *temp = NULL;
    temp = strtok(arry_temp, ".");
    
    while(temp !=NULL)
    {
        result[j] = atoi(temp); 
        j++;
       temp = strtok(NULL, ".");
    }
    return  result;
}

//判断是否是统一网段
int is_samenet(char *mask, char *ip1, char *ip2)
{
    //合法性检查
   if( is_legal( mask, MASK) || is_legal( ip1, IP)|| is_legal( ip2, IP))
       return  1;
   
    //转为unsigned char
        
    unsigned char mask_int[4] = {0};
    unsigned char ip1_int[4] = {0};
    unsigned char ip2_int[4] = {0};
    str2arr(mask, mask_int);
    str2arr(ip1, ip1_int);    
    str2arr(ip2, ip2_int);
    
    //比较
    for(int i = 0; i < 4; i++)
    {
       if( (mask_int[i] & ip1_int[i]) != (mask_int[i] & ip2_int[i]))
         return 2;
    }
    return 0;
    
}


int main()
{
  unsigned char mask[32] = {0};
  unsigned char ip_1[32] = {0}; 
  unsigned  ip_2[32] = {0}; 

    
   //获取掩码
   while(scanf("%s", mask) != EOF)
   {
       scanf("%s", ip_1);
       scanf("%s", ip_2);
       printf("%d\n", is_samenet(mask, ip_1, ip_2));
   }
  return 0;
}

发表于 2021-09-01 13:22:04 回复(0)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int valid(char* ip, int ismask){
    char local_ip[16];
    strcpy(local_ip, ip);
    char* part;
    part = strtok(local_ip, ".");
    
    int last = 1;
    
    while (part){
        int p = atoi(part);
        if(p > 255 || p < 0) return 0;
        
        if (ismask){
            int p_list[10] = {0};
            p_list[0] = last;
            for (int i = 8; i >= 1; i--){
                p_list[i] = p % 2;
                p = p / 2;
            }
            for (int i = 0; i < 9; i++) if (p_list[i + 1] > p_list[i]) return 0; 
            last = p_list[8];
        }
        
        part = strtok(NULL, ".");
    }
    return 1;
}

int pow(int a, int b){
    int ret = 1;
    for (int i = 0; i < b; i++) ret*=a;
    return ret;
}

long subnet(char* mask, char*ip){
    char local_mask[16];
    char local_ip[16];
    strcpy(local_mask, mask);
    strcpy(local_ip, ip);
    
    char parts_mask[4][4] = {0};
    char parts_ip[4][4] = {0};
    
    char* p = strtok(local_mask, ".");
    for (int i = 0; i < 4; i++) {
        strcpy(parts_mask[i], p);
        p = strtok(NULL, ".");
    }
    
    p = strtok(local_ip, ".");
    for (int i = 0; i < 4; i++) {
        strcpy(parts_ip[i], p);
        p = strtok(NULL, ".");
    }
    
    long ret = 0;
    for (int i = 0; i < 4; i++){
        long a = atoi(parts_mask[i]);
        long b = atoi(parts_ip[i]);
        
        long c = pow(2, (3-i)*8);
        ret += (a & b) * c;
    }
    
    return ret;
}

int main(){
    char ip1[16];
    char ip2[16];
    char mask[16];
    
    while (scanf("%s %s %s", mask, ip1, ip2) == 3){
        
        if ((valid(mask, 1) && valid(ip1, 0) && valid(ip2, 0)) == 0) printf("1\n");
        else if (subnet(mask, ip1) - subnet(mask, ip2) == 0) printf("0\n");
        else printf("2\n");
    }
}


发表于 2021-08-27 15:47:48 回复(0)