[백준] 2064번: IP 주소

Narcoker·2023년 5월 28일
0

코딩테스트

목록 보기
102/150

문제

네트워크에 연결되어 있는 컴퓨터들은 각각 하나의 IP 주소를 갖게 된다. 그리고 이러한 IP 주소를 갖는 컴퓨터들이 여러 개 모여서 하나의 IP 네트워크를 구성하게 된다. IP 네트워크는 ‘네트워크 주소’와 ‘네트워크 마스크’라는 두 개의 정보로 표현된다.

IP 주소는 네 개의 바이트로 구성되어 있으며, 각각을 10진수로 나타내고(앞에 0을 붙이지 않은 형태로) 사이에 점을 찍어 주소를 표현한다. 바이트이기 때문에 각각의 수는 0부터 255까지의 값을 갖게 된다. 네트워크 주소와 네트워크 마스크 역시 같은 형식으로 나타낸다.

IP 네트워크에 대해 올바르게 이해하기 위해서는 위와 같은 주소를 2진수로 이해하면 된다. 즉, 각각의 바이트를 ㅅ8자리의 이진수로 나타내고, 이를 네 개 붙여놓은(앞에서부터) 32자리의 이진수를 생각해 보자. IP 네트워크에는 기본적으로 2m 개의 컴퓨터(혹은 IP 주소)가 할당될 수 있다. 이 경우의 네트워크 주소는 앞의 32-m 자리가 임의의 수(0 또는 1)로 구성되어 있고, 뒤의 m자리는 0으로 채워지게 된다. 네트워크 마스크는 앞의 32-m 자리가 1로 채워져 있고, 뒤의 m자리는 0으로 채워지게 된다. 이와 같은 IP 네트워크에는 앞의 32-m 자리가 네트워크 주소와 일치하는 모든 IP들이 포함되게 된다.

예를 들어 네트워크 주소가 194.85.160.176이고, 네트워크 마스크가 255.255.255.248인 경우를 생각해 보자. 이 경우, 이 네트워크에는 194.85.160.176부터 194.85.160.183까지의 8개의 IP 주소가 포함된다.

어떤 네트워크에 속해있는 IP 주소들이 주어졌을 때, 네트워크 주소와 네트워크 마스크를 구해내는 프로그램을 작성하시오. 답이 여러 개인 경우에는 가장 크기가 작은(포함되는 IP 주소가 가장 적은, 즉 m이 최소인) 네트워크를 구하도록 한다.

입력

첫째 줄에 정수 n(1 ≤ n ≤ 1,000)이 주어진다. 다음 n개의 줄에는 각 컴퓨터의 IP 주소가 주어진다.

출력

첫째 줄에 네트워크 주소를, 둘째 줄에 네트워크 마스크를 출력한다.

입출력 예제

풀이

ide 에서 실행하면 원하는 값대로 나오지만
백준에서 실행하면 valueError 가 발생한다.
이유는 찾지 못했다.

비트마스킹을 활용한 풀이
서브넷 마스크를 먼저 구하고 네트워크 주소를 구한다.
네트워크 주소를 구하는 방법은 서브넷 마스크(이진수) 와 주어진 네트워크 주소 중 하나를
& 연산 하면 된다.

서브넷 마스크를 구하기 위해서 문자열의 ip주소를 십진수로 바꾼다.
이후 같은 비트가 같은 범위를 구한다.

서브넷 마스크와 주어진 네트워크 주소 중 하나를 선택해서 & 연산하여
네트워크 주소를 구한다.

서브넷 마스크와 네트워크 주소를 문자열화한다.
십진수를 이진수로 변환하고 문자열 슬라이싱을 활용해서
8비트씩 쪼갠 후 그 값을 다시 십진수화한다.
A, B, C, D 클래스를 모두 만든 후
해당 값들을 . 붙여서 주소 형식의 문자열로 만든다.

N = int(input())
ip_addrs = [input() for _ in range(N)]
print(N)

def solution(N, ip_addrs):
    def ip_to_int(ip):
        a, b, c, d = list(map(int, ip.split(".")))
        result = a << 24 | b << 16 | c << 8 | d
        return result

    def get_subnet_addrs(ip_addrs):
        result = 0
        for i in range(31, -1, -1):
            bit = 1 << i
            check = False

            for j in range(1, N):
                if (ip_addrs[0] & bit) != (ip_addrs[j] & bit):
                    check = True
                    break

            if check:
                break
            else:
                result |= bit

        return result

    def int_to_ip(num):
        num_to_bin = bin(num)[2:]
        a = int(num_to_bin[:8], 2)
        b = int(num_to_bin[8:16], 2)
        c = int(num_to_bin[16:24], 2)
        d = int(num_to_bin[24:], 2)

        return f'{a}.{b}.{c}.{d}'

    for i in range(len(ip_addrs)):
        ip_addrs[i] = ip_to_int(ip_addrs[i])

    subnet_address = get_subnet_addrs(ip_addrs)
    net_address = ip_addrs[0] & subnet_address

    print(int_to_ip(net_address))
    print(int_to_ip(subnet_address))

    return


solution(N, ip_addrs)
profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글