Unicode 도구
Unicode 코드포인트 변환, 문자 상세 정보 조회, 문자열 분해 분석을 제공합니다. 문자를 입력하면 코드포인트와 UTF-8/16/32 인코딩 바이트를 확인할 수 있습니다.
문자 → 코드포인트 변환
문자를 입력하면 각 문자의 코드포인트와 UTF 인코딩 바이트를 표시합니다.
코드포인트 → 문자 변환
코드포인트를 입력하면 해당 문자와 상세 정보를 표시합니다. U+0041, 0x0041, 65 형식을 지원하며, 여러 개를 공백·쉼표·줄바꿈으로 구분하여 입력할 수 있습니다.
바이트 시퀀스 → 문자열
16진수 바이트를 입력하면 지정한 인코딩으로 디코드합니다. 공백·쉼표·0x 접두사를 허용합니다.
문자열 분해 분석
문자열의 각 grapheme 클러스터를 분해하여 구성 코드포인트, 서로게이트 페어, 결합 문자 등을 시각화합니다.
Unicode 정규화 (NFC / NFD / NFKC / NFKD)
동일해 보이는 문자열이라도 결합 문자(combining mark) 순서나 호환 분해 여부에 따라 바이트 표현이 달라질 수 있습니다. 정규화는 이를 표준화하여 비교·검색·DB 저장 시 일관성을 확보합니다.
- NFC (Canonical Composition): 분해 후 재조합. 대부분의 파일 시스템·웹 표준 권장.
- NFD (Canonical Decomposition): 최대 분해. macOS HFS+가 사용.
- NFKC (Compatibility Composition): 호환 분해 후 재조합.
fi→fi,①→1같은 변환 포함. - NFKD (Compatibility Decomposition): 최대 호환 분해. 검색 키 정규화에 주로 사용.
Unicode 할당 대역
Unicode는 17개 플레인(plane)으로 구성되며, 각 플레인은 65,536개의 코드포인트를 포함합니다. 블록을 플레인별 또는 언어/스크립트별로 탐색할 수 있습니다.
UTF 인코딩 개요
Unicode는 전 세계 모든 문자를 하나의 코드 체계로 표현합니다. 코드포인트(code point)는 U+0000부터 U+10FFFF까지의 범위를 가지며, 실제 바이트 표현은 인코딩 방식에 따라 달라집니다.
UTF-8
가변 길이 인코딩으로, ASCII 호환성을 유지하면서 1~4바이트로 모든 Unicode 문자를 표현합니다. 리눅스 커널과 대부분의 인터넷 프로토콜에서 기본 인코딩으로 사용합니다.
| 코드포인트 범위 | 바이트 수 | 비트 패턴 |
|---|---|---|
| U+0000 ~ U+007F | 1 | 0xxxxxxx |
| U+0080 ~ U+07FF | 2 | 110xxxxx 10xxxxxx |
| U+0800 ~ U+FFFF | 3 | 1110xxxx 10xxxxxx 10xxxxxx |
| U+10000 ~ U+10FFFF | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
UTF-16
BMP(Basic Multilingual Plane, U+0000~U+FFFF) 문자는 2바이트, 그 밖의 문자는 서로게이트 페어(surrogate pair)를 사용하여 4바이트로 표현합니다. Windows와 Java에서 내부 문자열 인코딩으로 사용합니다.
서로게이트 페어 (Surrogate Pair)
Unicode 초기 설계(UCS-2)에서는 모든 문자를 16비트(2바이트)로 표현할 수 있다고 가정했습니다. 그러나 전 세계 문자를 수용하면서 65,536개(U+0000~U+FFFF)로는 부족해졌고, 코드포인트 범위가 U+10FFFF까지 확장되었습니다. UTF-16은 BMP 밖의 문자를 표현하기 위해 서로게이트 페어라는 메커니즘을 도입했습니다.
동작 원리
BMP에서 U+D800~U+DFFF 영역(2,048개)은 문자를 할당하지 않고 서로게이트 용도로 예약합니다. 이 영역을 두 구간으로 나눕니다.
| 구간 | 범위 | 개수 | 역할 |
|---|---|---|---|
| High Surrogate | U+D800 ~ U+DBFF | 1,024 | 상위 10비트 저장 |
| Low Surrogate | U+DC00 ~ U+DFFF | 1,024 | 하위 10비트 저장 |
High Surrogate 1개 + Low Surrogate 1개를 조합하면 1,024 × 1,024 = 1,048,576개의 보충 문자를 표현할 수 있으며, 이는 U+10000~U+10FFFF 범위와 정확히 일치합니다.
변환 공식
코드포인트 cp (U+10000 이상)를 서로게이트 페어로 변환하는 공식입니다.
u = cp - 0x10000 // 0x00000 ~ 0xFFFFF (20비트)
hi = 0xD800 + (u >> 10) // High Surrogate (상위 10비트)
lo = 0xDC00 + (u & 0x3FF) // Low Surrogate (하위 10비트)
역변환(서로게이트 페어 → 코드포인트)은 다음과 같습니다.
cp = 0x10000 + ((hi - 0xD800) << 10) + (lo - 0xDC00)
예시: 🌍 (U+1F30D)
| 단계 | 계산 | 결과 |
|---|---|---|
| 코드포인트 | U+1F30D (127,757) | |
| 오프셋 | 0x1F30D - 0x10000 | 0x0F30D |
| 상위 10비트 | 0x0F30D >> 10 = 0x3C | |
| 하위 10비트 | 0x0F30D & 0x3FF = 0x30D | |
| High Surrogate | 0xD800 + 0x3C | 0xD83C |
| Low Surrogate | 0xDC00 + 0x30D | 0xDF0D |
따라서 🌍는 UTF-16에서 D83C DF0D로 인코딩됩니다.
주의사항
- 단독 서로게이트 금지: High Surrogate나 Low Surrogate가 짝 없이 단독으로 나타나면 잘못된(ill-formed) UTF-16 시퀀스입니다.
- JavaScript의 함정: JavaScript의
String.length는 UTF-16 코드 유닛 수를 반환합니다. 이모지 등 BMP 밖 문자는 길이가 2로 계산됩니다. 올바른 문자 수를 구하려면[...str].length또는Intl.Segmenter를 사용해야 합니다. - C/커널에서의 주의: 리눅스 커널은 내부적으로 UTF-8을 사용하므로 서로게이트 코드포인트(U+D800~U+DFFF)가 UTF-8 바이트 스트림에 나타나면 유효하지 않은 시퀀스로 처리합니다.
- UTF-8에는 서로게이트 불필요: UTF-8은 자체적으로 가변 길이(1~4바이트)를 지원하므로 서로게이트 메커니즘이 필요하지 않습니다. 서로게이트는 오직 UTF-16에서만 사용합니다.
UTF-32
모든 코드포인트를 고정 4바이트로 표현합니다. 인덱싱이 O(1)이지만 메모리 효율이 낮아, 내부 처리용으로 주로 사용합니다.