URL 퍼센트 인코딩의 구조적 원리와 RFC 3986 표준 변환 분석
URL(Uniform Resource Locator)은 인터넷에 존재하는 특정 리소스의 고유한 위치를 가리키는 표준 식별자입니다. 웹 초기 설계 당시 URL은 7비트 US-ASCII 문자 집합의 일부 서브셋만을 사용하도록 정의되었기 때문에, 한글이나 일본어 같은 멀티바이트 유니코드 문자, 공백, 그리고 제어 문자를 직접 URL 경로에 포함하면 네트워크 장비나 웹 서버에서 파싱 오류가 발생하게 됩니다.
퍼센트 인코딩(Percent-Encoding, 또는 URL 인코딩)은 이러한 문제를 해결하기 위해 예약된 문자(Reserved Characters)와 비ASCII 유니코드 바이트를 % 기호 뒤에 2자리 16진수(Hexadecimal) 바이트 값으로 치환하는 W3C 및 IETF 표준 메커니즘입니다.
본 설명에서는 RFC 3986 표준에 따른 예약어와 비예약어 분류 체계, encodeURI와 encodeURIComponent의 내부 토큰 처리 차이점, UTF-8 멀티바이트(한글 3바이트) 인코딩 수학적 원리, 주요 언어별 구현 코드, 그리고 실무 보안 주의사항을 상세히 분석합니다.
RFC 3986 Strict 엄격 규격 지원
표준 encodeURIComponent에서 누락되는 느낌표(!), 작은따옴표('), 괄호(), 별표(*)까지 완벽하게 %HH 코드로 치환합니다.
encodeURI vs encodeURIComponent 듀얼 모드
전체 URL 주소 형태를 보존하는 모드와 쿼리 파라미터 값 전송을 위한 전체 치환 모드를 원클릭으로 선택할 수 있습니다.
공백 문자 %20 및 + 상호 변환
RFC 3986 웹 표준(%20)과 HTML Form 쿼리스트링 규격(+) 간의 공백 인코딩 방식을 자유롭게 제어합니다.
최근 변환 히스토리 로컬 저장
브라우저 로컬 스토리지를 활용하여 최근 변환한 URL 기록을 안전하게 보관하고 원클릭으로 다시 불러옵니다.
1. RFC 3986 표준에 따른 URL 문자 분류 체계 (Reserved vs Unreserved)
A-Z), 영문 소문자(a-z), 숫자(0-9), 하이픈(-), 밑줄(_), 마침표(.), 물결표(~) 총 66개 문자는 URL의 어떤 위치에서도 인코딩할 필요가 없습니다.:, /, ?, #, [, ], @ (스킴, 호스트, 경로, 쿼리, 프래그먼트를 구분)!, $, &, ', (, ), *, +, ,, ;, = (파라미터 키-값 분리 및 연산자) ), 줄바꿈(\n), 제어 문자(ASCII 0~31 및 127), 그리고 한글/한자/이모지 등 128 이상의 모든 UTF-8 멀티바이트 문자.2. 자바스크립트 내장 함수별 URL 문자 인코딩 비교표
함수마다 보존하는 문자와 인코딩하는 문자의 범위가 다르므로 용도에 맞는 함수 선택이 필수적입니다.
| 문자 범주 (Character Set) | 대표 예시 문자 | encodeURI() | encodeURIComponent() | RFC 3986 Strict |
|---|---|---|---|---|
| 영문 및 숫자 (Alphanumeric) | A-Z, a-z, 0-9 | 보존 (그대로 유지) | 보존 (그대로 유지) | 보존 (그대로 유지) |
| 비예약 특수문자 (Unreserved) | - _ . ~ | 보존 (그대로 유지) | 보존 (그대로 유지) | 보존 (그대로 유지) |
| URL 구조 예약어 (Gen-delims) | : / ? # [ ] @ | 보존 (URL 구조 유지) | %3A %2F %3F %23 등 인코딩 | %3A %2F %3F %23 등 인코딩 |
| 쿼리/파라미터 구분자 (Sub-delims) | & = + $ , ; | 보존 (파라미터 분리 유지) | %26 %3D %2B %24 등 인코딩 | %26 %3D %2B %24 등 인코딩 |
| 기타 특수문자 (RFC 3986 추가) | ! ' ( ) * | 보존 (인코딩 안 함) | 보존 (기본 JS 누락) | %21 %27 %28 %29 %2A 완벽 인코딩 |
| 한글 및 비ASCII 유니코드 | 가, 나, 다, 🚀, 你好 | UTF-8 %HH 바이트 인코딩 | UTF-8 %HH 바이트 인코딩 | UTF-8 %HH 바이트 인코딩 |
3. UTF-8 한글 및 유니코드의 3바이트 퍼센트 인코딩 수학적 원리
%EA%B0%80):U+AC00 (16진수)이며 2진수로는 1010 1100 0000 0000 (16비트)입니다.1110xxxx 10xxxxxx 10xxxxxx에 16비트를 상위 비트부터 채워 넣습니다.1110 + 1010 = 11101010 = 16진수 0xEA %EA10 + 110000 = 10110000 = 16진수 0xB0 %B010 + 000000 = 10000000 = 16진수 0x80 %80%EA%B0%80 (총 9글자)로 팽창하여 네트워크로 전송됩니다.4. 실무 웹 개발에서의 URL 인코딩 보안 및 안티패턴
%2520)을 다시 인코딩하면 % 기호 자체가 인코딩되어 %252520으로 중첩됩니다.redirect=https://evil.com과 같은 외부 URL을 파라미터로 전달받을 때는 반드시 화이트리스트 도메인 검증을 거친 후 안전하게 디코딩하여 리다이렉트해야 합니다.주요 프로그래밍 언어별 URL 인코딩 & 디코딩 구현 코드
웹 프론트엔드 및 백엔드 실무에서 즉시 활용할 수 있는 언어별 표준 URL 처리 스니펫입니다.
클라이언트 로컬 연산 FAQ
Q.URL 인코딩과 HTML 엔티티 인코딩은 무엇이 다른가요?
URL 인코딩(Percent-Encoding)은 웹 주소(URL) 경로 및 HTTP 전송 규격에서 ASCII 이외의 문자와 예약어를 %20, %EA%B0%80처럼 16진수 바이트 코드로 변환하는 프로토콜 규격입니다. 반면 HTML 엔티티 인코딩은 HTML 문서 내에서 <를 <, >를 >, &를 &로 변환하여 XSS(크로스 사이트 스크립팅) 공격을 방어하고 웹 브라우저의 HTML 파싱 에러를 방지하는 웹 문서 렌더링 규격입니다.
Q.encodeURI()와 encodeURIComponent() 중 어떤 것을 써야 하나요?
전체 URL 문자열(예: https://example.com/search?q=test)을 다룰 때는 프로토콜(https://), 물음표(?), 슬래시(/) 등의 주소 구조를 보존해야 하므로 encodeURI()를 사용해야 합니다. 반면 URL 뒤에 붙는 쿼리스트링 파라미터의 값(Value) 하나하나를 인코딩할 때는 ?나 &, = 기호까지 모두 안전하게 변환해야 파라미터가 쪼개지지 않으므로 반드시 encodeURIComponent()를 사용해야 합니다.
Q.공백(Space) 문자가 어떤 곳에서는 %20이고 어떤 곳에서는 +로 표시되는 이유는 무엇인가요?
IETF RFC 3986 웹 URI 표준 규격에서는 공백을 %20으로 인코딩하도록 규정하고 있습니다. 반면 W3C HTML 폼(Form) 데이터 전송 규격(application/x-www-form-urlencoded)에서는 공백을 + 기호로 치환하도록 정의되었습니다. 따라서 일반적인 URL 경로나 REST API 호출 시에는 %20을 사용하고, 웹 폼 전송 데이터 파싱 시에는 +를 공백으로 해석합니다.
Q.한글 1글자는 URL 인코딩 시 왜 9글자(%XX%XX%XX)로 변환되나요?
현대 웹은 전 세계 문자를 UTF-8 유니코드 규격으로 처리합니다. UTF-8에서 한글 음절 1글자는 3바이트(24비트)의 메모리 공간을 차지합니다. URL 인코딩은 1바이트(8비트)마다 % 기호와 2자리 16진수(총 3글자)로 변환하므로, 3바이트 글자(예: '가' %EA%B0%80)로 변환되어 전송됩니다.
Q.RFC 3986 Strict 인코딩이란 무엇인가요?
자바스크립트의 표준 encodeURIComponent() 함수는 역사적 이유로 느낌표(!), 작은따옴표('), 여는 괄호((), 닫는 괄호()), 별표(*)의 5개 문자를 인코딩하지 않고 그대로 남겨둡니다. 하지만 최신 OAuth 1.0/2.0 서명 생성이나 엄격한 REST API 서버에서는 이 5개 문자도 퍼센트 인코딩(%21, %27, %28, %29, %2A)을 요구하므로, 이를 완전히 준수하는 모드를 RFC 3986 Strict라고 부릅니다.
Q.URL 디코딩 시 "URI malformed" 에러가 발생하는 이유는 무엇인가요?
퍼센트 인코딩 문자열 중간에 % 기호 뒤에 올바른 2자리 16진수가 오지 않거나(예: %G1, %A), 3바이트 UTF-8 한글 코드 중 일부 바이트가 잘려 나간 경우(예: %EA%B0만 있고 마지막 바이트 누락) 발생합니다. 본 도구는 이러한 불완전한 입력이 들어왔을 때 사용자 친화적인 에러 알림과 함께 원본 입력을 안전하게 보존합니다.
Q.변환하려는 URL에 비밀번호나 개인정보가 포함되어 있어도 안전한가요?
네, 안전합니다. Toolbase의 모든 도구는 사용자 컴퓨터의 브라우저 로컬 자바스크립트 엔진 메모리 내에서만 동작합니다. 입력하신 텍스트와 URL은 원격 서버나 외부 로깅 시스템으로 전송되지 않습니다.
Q.URL 인코딩을 데이터 암호화(Encryption) 용도로 사용할 수 있나요?
절대 불가능합니다. URL 인코딩은 문자 손실 없는 네트워크 전송을 위한 공개 데이터 변환(Encoding) 규격일 뿐이며, 누구나 원터치로 디코딩할 수 있어 비밀성을 전혀 보장하지 않습니다. 민감한 정보는 반드시 AES-256이나 HTTPS/TLS 같은 암호화 알고리즘을 사용해야 합니다.