백준 3107 - IPv6

SEAN·2025년 4월 30일

Problem 💻

문제

IPv6은 길이가 128비트인 차세대 인터넷 프로토콜이다.

IPv6의 주소는 32자리의 16진수를 4자리씩 끊어 나타낸다. 이때, 각 그룹은 콜론 (:)으로 구분해서 나타낸다.

예를 들면, 다음과 같다.

2001:0db8:85a3:0000:0000:8a2e:0370:7334

32자리의 16진수는 사람이 읽고 쓰기에 불편하고, 대부분의 자리가 0이기 때문에 아래와 같이 축약할 수 있다.

  1. 각 그룹의 앞자리의 0의 전체 또는 일부를 생략 할 수 있다. 위의 IPv6을 축약하면, 다음과 같다
2001:db8:85a3:0:00:8a2e:370:7334
  1. 만약 0으로만 이루어져 있는 그룹이 있을 경우 그 중 한 개 이상 연속된 그룹을 하나 골라 콜론 2개(::)로 바꿀 수 있다.
2001:db8:85a3::8a2e:370:7334

2번째 규칙은 모호함을 방지하기 위해서 오직 한 번만 사용할 수 있다.

올바른 축약형 IPv6주소가 주어졌을 때, 이를 원래 IPv6 (32자리의 16진수)로 복원하는 프로그램을 작성하시오.

입력

첫째 줄에 올바른 IPv6 주소가 주어진다. 이 주소는 최대 39글자이다. 또한, 주소는 숫자 0-9, 알파벳 소문자 a-f, 콜론 :으로만 이루어져 있다.

출력

첫째 줄에, 입력으로 주어진 IPv6의 축약되지 않은 형태를 출력한다.

예제 입력 1

25:09:1985:aa:091:4846:374:bb

예제 출력 1

0025:0009:1985:00aa:0091:4846:0374:00bb

Solution 💡

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String address = br.readLine().trim();
        System.out.println(normIPv6(address));
    }
    
    static String expandIPv6(String address) {
        String[] parts = address.split(":");
        StringBuilder result = new StringBuilder();
        
        for (int i = 0; i < parts.length; i++) {
            if (!parts[i].isEmpty()) {
               
                while (parts[i].length() < 4) {
                    parts[i] = "0" + parts[i];
                }
                result.append(parts[i]);
            } else {
                result.append(parts[i]);
            }
            
            if (i < parts.length - 1) {
                result.append(":");
            }
        }
        
        return result.toString();
    }
    
    static String normIPv6(String address) {
        if (address.contains("::")) {
            String[] split = address.split("::", 2);
            String left = split[0];
            String right = split.length > 1 ? split[1] : "";
            
            String[] leftParts = left.isEmpty() ? new String[0] : left.split(":");
            String[] rightParts = right.isEmpty() ? new String[0] : right.split(":");
            
            int omit = 8 - (leftParts.length + rightParts.length);
            
            StringBuilder expandedAddress = new StringBuilder();

            for (int i = 0; i < leftParts.length; i++) {
                expandedAddress.append(leftParts[i]);
                expandedAddress.append(":");
            }

            for (int i = 0; i < omit; i++) {
                expandedAddress.append("0");
                expandedAddress.append(":");
            }

            for (int i = 0; i < rightParts.length; i++) {
                expandedAddress.append(rightParts[i]);
                if (i < rightParts.length - 1) {
                    expandedAddress.append(":");
                }
            }
            
            return expandIPv6(expandedAddress.toString());
        } else {
            return expandIPv6(address);
        }
    }
}
profile
성장하는 BE 개발자 입니다.

0개의 댓글