URL 인코드 / 디코드

URL 컴포넌트와 쿼리 문자열을 즉시 인코딩·디코딩합니다. 무료, 브라우저에서 처리.

  • 브라우저에서 처리
  • 데이터가 브라우저 밖으로 나가지 않습니다
  • 무료 · 회원가입 불필요
인코딩은 encodeURIComponent로 URL 구성 요소 하나를 처리하며 : / ? & = # 같은 구분자도 인코딩합니다. 디코딩은 UTF-8 퍼센트 인코딩 바이트를 읽습니다. 방향을 바꾸면 현재 입력을 즉시 변환합니다.
공백을 +로 옵션을 켜면 URLSearchParams 폼 인코딩을 사용합니다. a b+c는 a+b%2Bc가 되며 ! 작은따옴표 ( ) ~도 인코딩합니다. 디코딩은 +를 공백으로 읽습니다. 옵션을 끄면 공백은 %20이 되고 디코딩에서 +는 그대로 유지됩니다.
교체는 두 입력란의 내용과 방향을 바꿉니다. 대기 중인 변환을 취소하고 교체된 값을 유지합니다. 입력을 편집하거나 옵션을 바꾸면 다시 변환합니다.
지우기는 두 입력란과 상태를 비우고 대기 중인 변환과 저장을 취소하며 저장된 입력을 삭제합니다. 도구에 초점이 있을 때 Ctrl/⌘+L로도 같은 작업을 합니다. 방향과 폼 데이터 옵션은 유지합니다.
입력을 멈춘 뒤 300밀리초 후 결과를 갱신합니다. 짝이 없는 UTF-16 서로게이트는 인코딩할 수 없습니다. 디코딩 중 잘못된 % 이스케이프나 UTF-8 바이트의 위치를 표시합니다. GBK, Shift_JIS, EUC-KR은 지원하지 않습니다. 마지막 입력은 500밀리초 후 이 브라우저에 저장합니다.
복사는 현재 출력 전체를 복사합니다. 실패하면 출력을 선택하여 직접 복사하세요.
자세한 가이드 읽기 URL 인코딩·디코딩 완벽 가이드: 퍼센트 인코딩 원리와 실전
예시·자세한 설명·자주 묻는 질문 실제 출력이 있는 예시, 다른 도구와의 차이, 자주 묻는 질문.

검색어를 쿼리 값으로 넣을 때

?q= 뒤에 검색어를 붙이기 전에 검색어를 하나의 ‘값’으로 인코딩해야 합니다. 그대로 두면 공백이나 &, =가 URL의 구분자로 읽힙니다.

서울 맛집 (강남)을 기본 설정으로 인코딩하면 %EC%84%9C%EC%9A%B8%20%EB%A7%9B%EC%A7%91%20(%EA%B0%95%EB%82%A8)이 됩니다. 한글 한 음절은 %XX 세 개, 공백은 %20이고, 괄호는 인코딩되지 않고 그대로 남습니다.

공백을 +로 (폼 데이터)를 켜면 같은 입력이 %EC%84%9C%EC%9A%B8+%EB%A7%9B%EC%A7%91+%28%EA%B0%95%EB%82%A8%29가 됩니다. 공백은 +로 바뀌고, 이번에는 괄호도 %28, %29로 인코딩됩니다. 브라우저의 폼 전송이나 URLSearchParams가 만드는 형식과 같습니다. 서명 값을 비교하는 API라면 상대가 어느 형식으로 계산하는지 먼저 확인하세요.

EUC-KR로 만들어진 오래된 주소

HTML 폼은 페이지 자체의 문자 인코딩으로 쿼리를 인코딩합니다(HTML Living Standard 4.10.22.5: 먼저 문서의 문자 인코딩을 사용). 그래서 EUC-KR로 작성된 페이지에서 전송된 ‘서울’은 UTF-8의 %EC%84%9C%EC%9A%B8이 아니라 %BC%AD%BF%EF가 됩니다.

이 값을 디코딩하면 깨진 글자를 보여 주는 대신 1번째 문자부터: %BC%AD%BF%EF은(는) 올바른 UTF-8이 아닙니다. EUC-KR 등 다른 인코딩의 텍스트는 여기서 디코딩할 수 없습니다.라고 표시하고 멈춥니다. EUC-KR은 WHATWG Encoding Standard에서 레거시 인코딩으로 분류되며, 읽으려면 인코딩을 지정할 수 있는 처리가 필요합니다. 예를 들어 Python에서는 urllib.parse.unquote('%BC%AD%BF%EF', encoding='euc-kr')로 서울을 얻습니다.

두 번 인코딩된 값

주소에 %25가 보이면 이미 인코딩된 값을 한 번 더 인코딩했을 가능성이 큽니다. % 자체가 %25로 바뀌기 때문입니다. 예를 들어 a b는 a%20b가 되고, 한 번 더 인코딩하면 a%2520b가 됩니다. 이런 값을 디코딩 칸에 넣고 한 번 풀면 직전 단계가 보이므로, 어느 단계에서 인코딩이 중복됐는지 거슬러 올라가 확인할 수 있습니다.

이 도구를 쓰기 좋은 경우

  • 쿼리 값에 공백, &, =, #, 한글이 들어갈 때.
  • 주소 전체를 다른 주소의 파라미터로 넘길 때(로그인 후 돌아갈 주소 등). :와 /도 인코딩되므로 하나의 값으로 전달됩니다.
  • 바로 열어 볼 완전한 주소를 정리하는 용도에는 맞지 않습니다. 구분자까지 인코딩되어 링크로 쓸 수 없게 됩니다. 이때는 URL 파서에서 파라미터를 하나씩 고치세요.

제한 사항

  • UTF-8만 지원하며 인코딩을 추측하지 않습니다. EUC-KR, CP949 등으로 만든 퍼센트 인코딩은 대부분 오류가 나지만, 바이트가 우연히 올바른 UTF-8이면 다른 글자로 바뀌어 표시되고 경고도 없습니다. 예를 들어 EUC-KR의 ‘홍’은 %C8%AB인데, 디코딩하면 ȫ가 됩니다.
  • 디코딩은 첫 번째 문제에서 멈추고 위치를 알려 줍니다. 끝에 홀로 있는 100%의 %도 오류입니다.
  • 기본 인코딩은 ! ' ( ) *를 그대로 둡니다(encodeURIComponent의 규칙). 서명 계산 등에서 %21 %27 %28 %29 %2A가 필요하면 직접 바꿔야 합니다.
  • encodeURI 모드는 없습니다.
  • 이모지 중간이 잘린 문자열(짝이 없는 서로게이트)은 인코딩할 수 없으며 위치를 표시합니다.

FAQ

URL 인코딩이란 무엇입니까?

URL 인코딩(퍼센트 인코딩, RFC 3986 2.1절)은 문자의 UTF-8 바이트를 하나씩 %와 16진수 두 자리로 쓰는 방식입니다. 공백은 %20, &는 %26이 되고, 한글 음절은 3바이트이므로 '한'은 %ED%95%9C가 됩니다.

encodeURI와 encodeURIComponent의 차이는 무엇입니까?

encodeURI는 URL 전체를 대상으로 하며 ; , / ? : @ & = + $ # 같은 구분자를 그대로 둡니다. encodeURIComponent는 쿼리 값처럼 URL의 한 부분을 대상으로 하며 이 구분자들도 인코딩합니다. 영문자, 숫자와 - _ . ! ~ * ' ( )는 둘 다 인코딩하지 않습니다. [와 ]는 encodeURI에서도 %5B, %5D가 됩니다. 이 도구는 encodeURIComponent를 사용합니다.

디코딩해도 +가 남는 이유는 무엇입니까?

decodeURIComponent는 %XX만 되돌립니다. 공백을 +로 쓰는 것은 HTML 폼 형식(application/x-www-form-urlencoded)의 규칙이고 퍼센트 인코딩의 규칙이 아니므로, 기본 설정에서는 a+b가 그대로 a+b입니다. 공백을 +로 (폼 데이터)를 켜면 URLSearchParams처럼 +를 공백으로 읽습니다.

디코딩에 실패하는 이유는 무엇입니까?

% 뒤에 16진수 두 자리가 없거나(100%, %zz), 바이트가 올바른 UTF-8이 아닌 경우입니다. 중간에 잘린 %E4%B8이나 EUC-KR로 만든 %BC%AD가 후자에 해당합니다. 상태 줄에 위치와 문제가 된 부분이 표시됩니다.

EUC-KR로 만든 옛 주소는 어떻게 읽나요?

이 도구는 UTF-8만 읽기 때문에 EUC-KR로 인코딩된 '서울'(%BC%AD%BF%EF)은 1번째 문자부터 올바른 UTF-8이 아니라는 오류가 납니다. 인코딩을 지정할 수 있는 프로그램을 쓰세요. 예를 들어 Python의 urllib.parse.unquote('%BC%AD%BF%EF', encoding='euc-kr')는 서울을 돌려줍니다. 같은 글자를 UTF-8로 쓰면 %EC%84%9C%EC%9A%B8입니다.

데이터가 서버로 전송됩니까?

아니요. 변환은 브라우저 안에서 처리되며 결과는 JavaScript 내장 함수 encodeURIComponent / decodeURIComponent와 같습니다. 마지막 입력은 다음에 열 때 복원하도록 이 브라우저의 로컬 저장소에 저장되며, 지우기를 누르면 삭제됩니다.