首页 > 试题广场 >

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

[编程题]判断两个IP是否属于同一子网
  • 热度指数:160864 时间限制: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
          
# 做过ip分类和判断合法的有手就行

# 判断掩码错误
def mask_error(mask):
    if len(set(mask)) == 1:
        return True
    if '' in mask:
        return True
    else:
        for i in mask:
            if int(i) < 0 or int(i) > 255:
                return True
        if '01' in ''.join(bin(int(i))[2:].rjust(8, '0') for i in mask):
            return True

# 判断IP错误
def ip_error(ip):
    if len(ip) != 4:
        return True
    if '' in ip:
        return True
    # 非空
    else:
        for i in ip:
            if int(i) < 0 or int(i) > 255:
                return True

def isSame(mask: list, ip1: list, ip2: list):
    bin_mask = ''.join(bin(int(i))[2:].rjust(8, '0') for i in mask)
    bin_ip1 = ''.join(bin(int(i))[2:].rjust(8, '0') for i in ip1)
    bin_ip2 = ''.join(bin(int(i))[2:].rjust(8, '0') for i in ip2)
    temp = bin_mask.count('1')
    if bin_ip1[:temp] == bin_ip2[:temp]:
        return True

input_content=[]
for i in range(3):
    input_content.append(input())
mask=input_content[0].split('.')
ip1=input_content[1].split('.')
ip2=input_content[2].split('.')

if mask_error(mask) or ip_error(ip1) or ip_error(ip2):
    print(1)
else:
    if isSame(mask, ip1, ip2):
        print(0)
    else:
        print(2)

发表于 2024-03-29 22:51:11 回复(0)
ziwang = list(map(int,input().split(".")))
ip1 = list(map(int,input().split(".")))
ip2 = list(map(int,input().split(".")))
a = 0
for i in range(4):
    if ziwang[i] not in [0, 128, 192, 224, 240, 248, 252, 254, 255]:#这些数二进制均由连续的0和1组成
        a = 1
    elif ziwang != sorted(ziwang,reverse = True):
        a = 1
    elif max(ziwang + ip1 + ip2) > 255&nbs***bsp;min(ziwang + ip1 +ip2) < 0:
        a = 1
    elif ziwang[i] & ip1[i] != ziwang[i] & ip2[i]:
        a = 2
print(a)

发表于 2024-02-04 00:31:13 回复(0)
有大神帮忙看看吗,为什么会有例子过不去。我看结果应该是出现了12,那应该就是说先判断出现了错误的ip或者mask,然后还判断ip和mask是否同子网,不应该break之后就不会走下面的步骤了吗
import sys
import re


def getBin(str):
    str_bin = ""
    for i in str.split("."):
        str_bin += bin(int(i))[2:].rjust(8, "0")
    return str_bin


while True:
    try:
        mask = input()
        ip1 = input()
        ip2 = input()
        if re.search("\d+\.\d+\.\d+\.\d+", mask) is None:
            print('1')
            break
        else:
            for i in mask.split('.'):
                if 0 > int(i)&nbs***bsp;int(i) > 255:
                    print('1')
                    break
            if re.search("01", getBin(mask)):
                print('1')
                break
        if re.search("\d+\.\d+\.\d+\.\d+", ip1) is None:
            print('1')
            break
        else:
            for i in ip1.split('.'):
                if 0 > int(i)&nbs***bsp;int(i) > 255:
                    print('1')
                    break
        if re.search("\d+\.\d+\.\d+\.\d+", ip2) is None:
            print('1')
            break
        else:
            for i in ip2.split('.'):
                if 0 > int(i)&nbs***bsp;int(i) > 255:
                    print('1')
                    break
        if int(getBin(ip1), 2) & int(getBin(mask), 2) == int(getBin(ip2), 2) & int(getBin(mask), 2):
            print('0')
        else:
            print('2')
    except:
        break

发表于 2023-04-14 20:03:22 回复(0)
用例输入
254.255.0.0
85.122.52.249
10.57.28.117
预期输出
1
实际输出
2
为什么这个地址不合法啊
发表于 2022-12-13 23:21:55 回复(1)
# 先判断输入的ip是否合法
# 将每个ip翻译成二进制
# 将ip和子网掩码进行按位与运算
# 比较运算的结果
ip_list1 = input().split(".")
ip_list2 = input().split(".")
ip_list3 = input().split(".")

# 判断ip是否合法
def ip_is_legit(ip_list):
    flag = True
    for i in ip_list:
        if int(i) > 255 or int(i) < 0:
            flag = False
    return flag

# 将ip翻译成二进制
def ip_to_bin(ip_list):
    result_ip = ""
    for i in ip_list:
        temp = bin(int(i, 10))[2:]
#         print(temp,"temp")
        # 给不够8位的补0
        result_ip += ("0" * (8 - len(temp)) + temp)
    return result_ip
# 判断子网掩码是否合法
def sub_is_legit(ip_list):
    flag = True
    for s in ip_list:
        if int(s)<0 or int(s)>255:
            flag = False
    bin_ip = ip_to_bin(ip_list)
    if "01" in bin_ip and bin_ip != "00000000000000000000000000000001":
        flag = False    
    return flag
# 将ip和子网掩码按位与运算
def comp_ip(ip_1, ip_2):
    temp = ""
    for i in range(len(ip_1)):
        if ip_1[i] == "1" and ip_2[i] == "1":
            temp += "1"
        else:
            temp += "0"
    return temp

# 同时为真,合法
if sub_is_legit(ip_list1) and ip_is_legit(ip_list2) and ip_is_legit(ip_list3):
    tb1 = ip_to_bin(ip_list1)
    tb2 = ip_to_bin(ip_list2)
    tb3 = ip_to_bin(ip_list3)
#     print(tb1,tb2,tb3)
    cp1 = comp_ip(tb1, tb2)
    cp2 = comp_ip(tb1, tb3)
    if cp1 == cp2:
        print(0)
    else:
        print(2)
else:
    print(1)
发表于 2022-09-03 21:23:02 回复(1)
#痛苦,才知道&运算直接int
def matchh2(j, k, l):
    mch1 = []
    mch2 = []
    for i in range(4):
        mch1.append(int(j[i])&int(l[i]))
        mch2.append(int(k[i])&int(l[i]))
    return mch1 == mch2
def matchh(j, k, l):
    flag = 1
    for i in range(4):
        if int(j[i])&int(l[i]) != int(k[i])&int(l[i]):
            flag = 0
            break
    return flag


发表于 2022-07-27 19:10:03 回复(0)
# 格式错误 1, 属于同一子网络 0, 不属于2
# 判断格式
ziwangyanma = input().split('.')
ip1 = input().split('.')
ip2 = input().split('.')
flag = 1
for i in range(len(ip1)):
    if int(ziwangyanma[0]) != 255&nbs***bsp;int(ziwangyanma[3]) != 0:
        flag = 0
        print(1)
        break
    else:
        if (not 0 <= int(ip1[i]) <= 255)&nbs***bsp;(not 0 <= int(ip2[i]) <= 255)&nbs***bsp;(not 0 <= int(ziwangyanma[i]) <= 255):
            flag = 0
            print(1)
            break    
    


#转换二进制
def convert2bin(ip):
    bin_ip = []
    for ip_ in ip:
        temp = str(bin(int(ip_)))[2:]
        temp_length = len(temp)
        if temp_length < 8:
            temp = (8 - temp_length) * '0' + temp
        bin_ip.append(temp)
    ip_bin = '.'.join(bin_ip).strip('.')
#     print(ip_bin)
    return ip_bin

def cal_yu(ip, ziwangyanma):
    res = []
    ip = ip.split('.')
    ziwangyanma= ziwangyanma.split('.')
    for i, z in zip(ip,ziwangyanma):
        res_ = ''
        for index in range(8):
            temp = 0
            temp = int(i[index]) + int(z[index])
            if temp > 1:
                res_ += '1'
            else:
                res_ += '0'
        res.append(res_)
    res_str = '.'.join(res).strip('.')
    return res_str

if flag != 0:
    bin_ip1 = convert2bin(ip1)
    bin_ip2 = convert2bin(ip2)
    bin_ziwangyanma = convert2bin(ziwangyanma)
    str1 = cal_yu(bin_ip1, bin_ziwangyanma)
    str2 = cal_yu(bin_ip2, bin_ziwangyanma)
    if str1 == str2:
        print(0)
    else:
        print(2)

发表于 2022-07-18 23:06:11 回复(0)
python3 
while True:
    try:
        mask, mask_temp = input(), ""
        mask = mask.split(".")
        ip_1, ip_2 = input(), input()
        ip_1, ip_2 = ip_1.split("."), ip_2.split(".")
        # judge mask
        sign_mask = 1 # True: 1 False: 0
        for i in range(4):
            temp = mask[i]
            if not (0<=int(temp)<=255):
                sign_mask = 0
                print(1)
                break
            else:
                temp = "%08d"%(int((bin(int(temp, 10)))[2:]))
                mask_temp += temp
        if sign_mask:
            one_end, zero_start = mask_temp.rfind("1"), mask_temp.find("0")
            if one_end + 1 != zero_start:
                sign_mask = 0
                print(1)
        # judge ip
        if sign_mask:
            sign_ip = 1
            ip_1_temp, ip_2_temp = "", ""
            for i in range(4):
                temp_1, temp_2 = ip_1[i], ip_2[i]
                if not (0<=int(temp_1)<=255 and 0<=int(temp_2)<=255):
                    sign_ip = 0
                    print(1)
                    break
                else:
                    temp_1 = "%08d"%(int((bin(int(temp_1, 10)))[2:]))
                    temp_2 = "%08d"%(int((bin(int(temp_2, 10)))[2:]))
                    ip_1_temp += temp_1
                    ip_2_temp += temp_2
        if sign_mask == 1 and sign_ip == 1:
            mask_ip_1 = int(mask_temp[:16], 2) & int(ip_1_temp[:16], 2)
            mask_ip_2 = int(mask_temp[:16], 2) & int(ip_2_temp[:16], 2)
            if mask_ip_1 == mask_ip_2:
                print(0)
            else:
                print(2)
    except:
        break


发表于 2022-07-16 16:48:54 回复(0)
import re
 
# 地址转换为二进制
def trans(adr):
    res = [bin(int(i)).replace("0b", "").rjust(8, "0") for i in adr]
    return res

# 判断地址是否有效
def is_valid(adr):
    res = [int(x) for x in adr if 0 <= int(x) <= 255]
    if len(res) == 4:
        return True
    return False

# 判断地址是否属于子网掩码
def check_mask(adr):
    if is_valid(adr):
        mask_b = "".join(trans(adr))
        if re.search(r"^1+0+$", mask_b):
            return True
    return False
 
# IP地址与子网掩码进行与运算
def ip_mask(adr1, adr2):
    adr1_b = trans(adr1)
    adr2_b = trans(adr2)
    res = []
    for i in range(4):
        res.append(int(adr1_b[i]) & int(adr2_b[i]))
    return res


while True:
    try:
        mask = input().split('.')
        ip1 = input().split('.')
        ip2 = input().split('.')
        if is_valid(ip1) and is_valid(ip2) and check_mask(mask):
            # 运算结果是一样的判断是在同一个子网
            if ip_mask(ip1, mask) == ip_mask(ip2, mask):
                print(0)
            else:
                print(2)
        else:
            print(1)
    except:
        break

发表于 2022-07-14 00:53:26 回复(0)
def i2b(x):     # 十进制转二进制,输入输出均为字符串
    res = ''
    for i in x:
        temp = bin(int(i))[2:]
        temp = '0'*(8-len(temp)) + str(temp)
        res += temp
    return res

def isyanma(x):  # 判断是否为掩码,输入二进制字符串
    if x[0] == '0':
        return False
    else:
        for i in range(len(x)):
            if x[i] == '0':
                for j in range(i+1, len(x)):
                    if x[j] == '1':
                        return False
    return True

while True:
    try:
        yanma = input().split('.')
        IP1 = input().split('.')
        IP2 = input().split('.')
        l1 = []
        l2 = []
        n = 0
        if len(yanma) != 4&nbs***bsp;len(IP1) != 4&nbs***bsp;len(IP2) != 4:
            n = 1
        else:
            for i in range(4):
                yanma[i] = int(yanma[i])
                IP1[i] = int(IP1[i])
                IP2[i] = int(IP2[i])
                if max(yanma[i], IP1[i], IP2[i]) > 255&nbs***bsp;min(yanma[i], IP1[i], IP2[i]) < 0:
                    n = 1
                    break
            else:
                if not isyanma(i2b(yanma)):
                    n = 1
                else:
                    a = i2b(yanma)
                    b1 = i2b(IP1)
                    b2 = i2b(IP2)
                    for i in range(len(yanma)):
                        l1.append(int(b1[i]) & int(a[i]))
                        l2.append(int(b2[i]) & int(a[i]))
                    if l1 != l2:
                        n =2
        print(str(n))
    except:
        break
看了评论区发现大家对IP或掩码非法的情况判断都不是很全,不知道是不是我想太多。。。
发表于 2022-07-12 14:57:44 回复(0)
#已考虑掩码非法,100%通过
while True:
    try:
        x=list(map(int,input().split(".")))
        y=list(map(int,input().split(".")))
        z=list(map(int,input().split(".")))
        m=[]
        n=[]
        res=''
        for i in x:
            a=bin(i)[2:]
            b='0'*(8-len(a))+str(a)
            res+=b
            
       
        
       #注意判断子网掩码是否非法
        if  max(x+y+z)<=255 and min(x+y+z)>=0 and res.find('0')==res.rfind('1')+1:
           
        
            for i in range (len(x)):
               
                m.append(x[i]&y[i])
                #m[i]=m[i].replace("0b","")
                n.append(x[i]&z[i])
                #n[i] = n[i].replace("0b", "")
            if m==n:
                print("0")
            else:
                print("2")
        else:print("1")
    except:
        break

发表于 2022-07-05 15:37:44 回复(0)
#自定义判断函数
def check(copy,ip1,ip2):    
    copy = copy.split(".")   #提取单个数字
    ip1 = ip1.split(".")
    ip2 = ip2.split(".")
    IP1 = ""     #预留二进制空间
    IP2 = ""
    copy2 = ""
    note = 0    #留作记录,以免重复输出,判断逻辑有些散乱
    for i in range(4):   
        if int(copy[i]) > 255&nbs***bsp;int(ip1[i]) > 255&nbs***bsp;int(ip2[i]) > 255&nbs***bsp;\
        int(copy[i]) < 0&nbs***bsp;int(ip1[i]) < 0&nbs***bsp;int(ip2[i]) < 0:
            print(1)         #排除数字越界的情况
            note = 1         #记录该组数据已输出
            break
        else:
            n1 = bin(int(ip1[i],10))[2:].zfill(8)     #转换成二进制数
            n2 = bin(int(ip2[i],10))[2:].zfill(8)
            n3 = bin(int(copy[i],10))[2:].zfill(8)
            IP1 = IP1 + n1      #把几个二进制数组合在一起
            IP2 = IP2 + n2
            copy2 = copy2 + n3
    if copy2.count("10") ==1 and copy2.count("01") == 0:   #判断子网掩码是否有效,有效时:
        res1 = bin(int(IP1,2) & int(copy2,2))       #“与”运算
        res2 = bin(int(IP2,2) & int(copy2,2))
        if res1 == res2:    #运算结果比较
            print(0)
        else:
            print(2)
    else:              #子网掩码无效时:
        if note != 1:
            print(1)                       
while True:
    try:
        copy = input()
        ip1 = input()
        ip2 = input()
        check(copy,ip1,ip2)   #调用自定义函数
    except:
        break
#判断细节应该还可以优化
发表于 2022-05-25 17:47:06 回复(0)
def checip(ip):
    for i in ip:
        if int(i) > 255&nbs***bsp;int(i)<0:
            return False
    return True

def checkdns(dns):
    dnsbin=''
    if checip(dns):
        for d in dns:
            dnsbin += bin(int(d)).rjust(8, '0').replace('0b', '')
        if dnsbin.count('0') > 0 and dnsbin.count('1') > 0 and '01' not in dnsbin:
            return True
    return False



def getNet(dns,ip):
    rt = list()
    for i,j in zip(dns,ip):
        rt.append(int(i)&int(j))
    return rt

try:
    while True:
        dns=input().split('.')
        ip1=input().split('.')
        ip2=input().split('.')
        dnsbin=None
        okIp = checip(ip1) & checip(ip2) & checkdns(dns)
        if okIp:
            if getNet(dns,ip1) == getNet(dns,ip2):
                print(0)
            else:
                print(2)
        else:
            print(1)
   
except:
    exit()

发表于 2022-05-06 21:38:56 回复(0)
import sys
a = input()
ip1 = input()
ip2 = input()
s = ''
t = ''
d = ''
x,y,z = '','',''
qqq,eee = 0,''
www,rrr = 0,''
a1 = a.split('.')
ip11 = ip1.split('.')
ip22 = ip2.split('.')
for i in range(4):
    if int(a1[i]) < 0&nbs***bsp;  int(a1[i])  >255 or int(ip11[i]) < 0&nbs***bsp;  int(ip11[i])  >255 or int(ip22[i]) < 0&nbs***bsp;  int(ip22[i])  >255:
        print(1)
        sys.exit()
for i in a1:
    i = bin(int(i,10))[2:]
    if len(i) < 8 :
        i = (8 - len(i))*'0' + i
    s = s + i
index1 = s.find('0')
if '1' in s[index1:]:
    print(1)
    sys.exit()
for i in ip11:
    i = bin(int(i,10))[2:]
    if len(i) < 8 :
        i = (8 - len(i))*'0' + i
    t = t + i
for i in ip22:
    i = bin(int(i,10))[2:]
    if len(i) < 8 :
        i = (8 - len(i))*'0' + i
    d = d + i
x = t[0:9]+'.'+t[9:18]+'.'+t[18:26]+'.'+t[26:32]
y = d[0:9]+'.'+d[9:18]+'.'+d[18:26]+'.'+d[26:32]
z = s[0:9]+'.'+s[9:18]+'.'+s[18:26]+'.'+s[26:32]
x1 = x.split('.')
y1 = y.split('.')
z1 = z.split('.')
for i in range(len(x1)):
    qqq = int(x1[i]) & int(z1[i])
    eee = str(qqq)+eee
for i in range(len(y1)):
    www = int(y1[i]) & int(z1[i])
    rrr = str(www)+rrr
if int(eee) == int(rrr):
    print(0)
else:
    print(2)
发表于 2022-03-19 14:17:04 回复(0)
def ifmask(mask):
    a=[]
    for i in range(4):
        if 0<=int(mask[i])<=255:
            a.append(bin(int(mask[i]))[2:].rjust(8,'0'))
        else:
            return False
    b=''.join(a).rstrip('0')
    if '0' in b:
        return False
    else:
        return True
    
def cmp(ip1,ip2,mask):
    res1=[0]*4
    res2=[0]*4
    for i in range(4):
        if (ifmask(mask)==True) and 0<=int(ip1[i])<=255 and 0<=int(ip2[i])<=255:
            res1[i] = int(ip1[i]) & int(mask[i])
            res2[i] = int(ip2[i]) & int(mask[i])
        else:
            return 1
    if res1==res2:
        return 0
    else:
        return 2
while True:
    try:
        mask=input().split('.')
        ip1=input().split('.')
        ip2=input().split('.')
        print(cmp(ip1,ip2,mask))
    except:
        break
发表于 2022-03-18 15:14:48 回复(0)

这道题明显是字符串模拟题,用Python更好处理
用re + str.split都是很好处理的

import sys
import re

def main():
    ip_list = []
    res = ''
    for line in sys.stdin:
        line = line.strip('\n')
        ip_list.append(line)

    for i in range(0, len(ip_list), 3):
        mask_code = ip_list[i]
        ip_1 = ip_list[i + 1]
        ip_2 = ip_list[i + 2]
        mask_code_list = mask_code.split('.')
        # 找mask_code是否合法
        flag = False
        mask_code_str = ''
        for temp in mask_code_list:
            temp_b = str(bin(int(temp)))[2:]
            while len(temp_b) < 8 :
                temp_b = '0' + temp_b
            mask_code_str += temp_b

#         print(mask_code_str)
        obj = re.fullmatch('1*0*', mask_code_str)
        if obj is not None:
            flag = True
        else:
            print(1)
            flag = False

        # 先判断是否ip地址合法
        if flag == True:
            ip_1_list = ip_1.split('.')
            ip_2_list = ip_2.split('.')
            for j in range(0, 4):
                ip_1_temp = int(ip_1_list[j])
                ip_2_temp = int(ip_2_list[j])
                mask_code_temp = int(mask_code_list[j])
                if ip_1_temp > 255 or ip_1_temp < 0 or \
                        ip_2_temp > 255 or ip_2_temp < 0 or \
                        mask_code_temp > 255 or mask_code_temp < 0:
                    print(1)
                    flag = False
                    break

        if flag == True:
            is_same = True
            for j in range(0, 4):
                ip_1_temp = int(ip_1_list[j])
                ip_2_temp = int(ip_2_list[j])
                mask_code_temp = int(mask_code_list[j])
                net1_j = ip_1_temp & mask_code_temp
                net2_j = ip_2_temp & mask_code_temp
                if net1_j != net2_j:
                    print(2)
                    is_same = False
                    break
            if is_same == True:
                print(0)


if __name__ == '__main__':
    main()

发表于 2022-03-08 22:25:58 回复(0)