컴퓨터/프로그래밍

한글 ↔ 퓨닉스(Punycode) 한글도메인 변환 도구

발견하는 하루 2025. 6. 6. 15:50

코드 상세 설명: 한글 ↔ 퓨닉스(Punycode) 변환 도구
1. HTML 구조

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8"> <!-- 한국어 문자 지원 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 반응형 디자인 -->
    <title>한글 ↔ 퓨닉스 변환</title>
    <!-- CSS 스타일 -->
</head>
<body>
    <h1>한글 ↔ 퓨닉스 변환</h1>
    <form method="POST">
        <label for="domainInput">URL 또는 도메인 입력</label>
        <textarea id="domainInput" name="urls" required></textarea>
        <button type="submit">변환</button>
    </form>
    <!-- PHP 처리 결과 영역 -->
</body>
</html>

입력 폼: 사용자가 URL/도메인을 입력할 수 있는 텍스트 영역(<textarea>) 제공
버튼: 폼 제출용 파란색 버튼 (호버 시 색상 변경 효과)

 

2. PHP 핵심 로직
① 변환 함수

function toPunycode($domain) {
    return idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) 
        ?: "변환 실패";
}

function toUnicode($punycode) {
    return idn_to_utf8($punycode, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) 
        ?: "변환 실패";
}

idn_to_ascii(): 한글 도메인 → 퓨닉스 (예: 예시.한국 → xn--9d0bm4c.xn--3e0b707e)
idn_to_utf8(): 퓨닉스 → 한글 도메인 (예: xn--9d0bm4c → 예시)
오류 처리: 변환 실패 시 "변환 실패" 메시지 반환

 

② URL/도메인 처리 함수 (processLine)

function processLine($line) {
    // URL인 경우 (예: https://예시.한국/경로?쿼리=1)
    if (preg_match('/^https?:\/\//i', $line)) {
        $parsed = parse_url($line); // URL 파싱
        $host = $parsed['host']; // 도메인 추출
        
        // 도메인 변환
        $convertedHost = (strpos($host, 'xn--') === 0) 
                        ? toUnicode($host) 
                        : toPunycode($host);
        
        // URL 재구성
        return $parsed['scheme'] . '://' 
             . $parsed['host'] 
             . $parsed['path'] 
             . (isset($parsed['query']) ? '?'.$parsed['query'] : '');
    }
    // 도메인만 있는 경우 (예: 예시.한국)
    else {
        return (strpos($line, 'xn--') === 0) 
               ? toUnicode($line) 
               : toPunycode($line);
    }
}

parse_url(): URL을 구성 요소로 분해 (스키마, 호스트, 경로 등)
자동 감지: xn--로 시작하면 퓨닉스 → 한글, 아니면 한글 → 퓨닉스

 

③ 메인 처리 흐름

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = trim($_POST['urls']);
    $lines = explode("\n", $input); // 줄 단위 분리
    
    foreach ($lines as $line) {
        $converted = processLine($line); // 각 줄 처리
        
        // 결과 출력
        echo "<div class='result'>";
        if (preg_match('/^https?:\/\//', $converted)) {
            echo "<a href='$converted'>$converted</a>"; // URL 링크
        } else {
            echo htmlspecialchars($converted); // 일반 텍스트
        }
        echo "</div>";
    }
}

다중 입력 처리: 줄바꿈(\n)으로 구분된 여러 항목 동시 변환
XSS 방지: htmlspecialchars()로 사용자 입력 필터링

 

3. 동작 예시

                        입력 유형                           예시 입력                        변환 결과
한글 URL https://예시.한국/경로 https://xn--9d0bm4c/경로
퓨닉스 URL http://xn--9d0bm4c http://예시
한글 도메인 테스트.서울 xn--9d0bm4a.xn--3e0b707e
퓨닉스 도메인 xn--9d0bm4a 테스트

 

4. 주요 특징
      1.양방향 자동 변환
             -입력값을 분석해 한글/퓨닉스 여부 자동 판별
             -사용자가 변환 방향을 선택할 필요 없음

       2.복잡한 URL 지원
             -https://user:password@예시.한국:8080/path?q=1#fragment 같은 복합 URL 처리 가능
             -포트 번호, 경로, 쿼리 매개변수 등 모든 요소 보존

       3.대량 처리
             -100개 도메인을 한 번에 변환 가능 (줄바꿈으로 구분)

       4.보안 기능
             -htmlspecialchars()로 XSS 공격 방지
             -trim()으로 불필요한 공백 제거

 

최종코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>한글 ↔ 퓨닉스 변환</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        form {
            margin-bottom: 20px;
        }
        textarea {
            width: 100%;
            height: 150px;
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-sizing: border-box;
            resize: none;
        }
        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        .result {
            padding: 10px;
            background-color: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 5px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>

<h1>한글 ↔ 퓨닉스 변환</h1>

<form method="POST">
    <label for="domainInput">URL 또는 도메인 입력 (한글 또는 퓨닉스, 줄바꿈으로 구분):</label>
    <textarea id="domainInput" name="urls" placeholder="양방향 변환" required></textarea>
    <button type="submit">변환</button>
</form>

<?php
// 퓨닉스 변환 함수
function toPunycode($domain) {
    return idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: "변환 실패 (잘못된 형식)";
}

// 한글 변환 함수
function toUnicode($punycode) {
    return idn_to_utf8($punycode, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: "변환 실패 (잘못된 형식)";
}

// 도메인 또는 URL을 판별하여 변환
function processLine($line) {
    $line = trim($line);
    if ($line === "") return "";

    // URL인지 도메인인지 판별
    if (preg_match('/^https?:\/\//i', $line)) {
        // 전체 URL인 경우
        $parsed = parse_url($line);
        if (!$parsed || !isset($parsed['host'])) {
            return "잘못된 URL: " . htmlspecialchars($line);
        }
        $host = $parsed['host'];
        // 퓨닉스인지 한글인지 판별
        if (strpos($host, 'xn--') === 0) {
            $convertedHost = toUnicode($host);
        } else {
            $convertedHost = toPunycode($host);
        }
        // 변환된 URL 재구성
        $scheme = isset($parsed['scheme']) ? $parsed['scheme'] . '://' : '';
        $user = isset($parsed['user']) ? $parsed['user'] . (isset($parsed['pass']) ? ':' . $parsed['pass'] : '') . '@' : '';
        $port = isset($parsed['port']) ? ':' . $parsed['port'] : '';
        $path = isset($parsed['path']) ? $parsed['path'] : '';
        $query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
        $fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
        return $scheme . $user . $convertedHost . $port . $path . $query . $fragment;
    } else {
        // 도메인만 입력한 경우
        // 퓨닉스인지 한글인지 판별
        if (strpos($line, 'xn--') === 0) {
            return toUnicode($line);
        } else {
            return toPunycode($line);
        }
    }
}

// 사용자 입력 처리 및 결과 출력
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = trim($_POST['urls']);
    $lines = explode("\n", $input); // 줄바꿈으로 입력을 분리
    echo "<h2>변환 결과</h2>";
    foreach ($lines as $line) {
        $line = trim($line);
        if ($line !== "") {
            $converted = processLine($line);
            echo "<div class='result'>";
            // URL이면 링크로, 아니면 그냥 출력
            if (preg_match('/^https?:\/\//i', $converted)) {
                echo "<a href='" . htmlspecialchars($converted) . "' target='_blank'>" . htmlspecialchars($converted) . "</a>";
            } else {
                echo nl2br(htmlspecialchars($converted));
            }
            echo "</div>";
        }
    }
}
?>

</body>
</html>