-
NFC / NFD란 무엇이고, 왜 문자열 이슈를 만든 걸까 ⁉️기타 2026. 2. 4. 06:42
웹이나 앱에서 문자열을 다루다 보면 가끔 이런 이상한 상황을 만난다.
- 화면에 똑같이 보이는데 문자열 비교가 실패함
- 파일명이 같아 보이는데 OS마다 다르게 취급됨
- 검색이 안 되거나, 중복 체크가 통과됨
이 문제의 원인은 종종 유니코드 정규화(Normalization), 그중에서도 NFC와 NFD의 차이에 있다.

유니코드 정규화란?
유니코드는 같은 글자를 여러 방식으로 표현할 수 있다.
예를 들어 é는 다음 두 가지 방식으로 표현 가능하다.
1️⃣ NFC (Normalization Form C)
- 하나의 코드 포인트로 결합된 형태
é → U+00E92️⃣ NFD (Normalization Form D)
- 기본 문자 + 결합 문자로 분리된 형태
e + ́ → U+0065 + U+0301👉 눈에는 똑같이 보이지만, 내부 문자열은 다르다.
NFC vs NFD 차이 정리 🧹
- 형태
- NFC: 문자가 하나로 결합된(composed) 형태
- NFD: 문자가 기본 문자 + 결합 문자로 분해(decomposed)된 형태
- 문자열 길이
- NFC: 하나의 코드 포인트로 표현되는 경우가 많아 보통 더 짧음
- NFD: 결합 문자가 분리되어 들어가므로 문자열이 더 길어질 수 있음
- 비교 안정성
- NFC: 문자열 비교 시 안정적이며 대부분의 환경에서 동일하게 동작
- NFD: 정규화되지 않으면 같은 글자라도 비교 실패 가능성 존재
- 사용 빈도 / 환경
- NFC: 웹 브라우저, JavaScript, 대부분의 웹 서비스에서 기본적으로 사용
- NFD: 일부 운영체제 환경(특히 macOS 파일 시스템)에서 사용
언제 문제가 발생할까 ??
1. 문자열 비교 (===) 실패
const a = "é"; // NFC const b = "e\u0301"; // NFD a === b; // falseUI에서는 동일해 보이는데, 로직에서는 다른 값으로 인식된다.

콘솔로 실제 찍어보면 ??

이해할 수 없는 문제가 발생한다...

2. macOS 파일 시스템 이슈
macOS는 기본적으로 파일명을 NFD 형태로 저장한다.
- 업로드된 파일명
- 서버에서 생성한 파일명
- 윈도우/리눅스 환경과의 충돌
=> 동일한 이름인데 중복 파일로 처리되거나, 파일을 찾지 못하는 문제가 발생한다.
3. 검색 / 필터 / 중복 체크 실패
이런 이슈가 만약, 검색/필터/중복 체크 같은 실무적인 상황에서 발생한다면 ???
list.includes(inputValue); // false- 사용자 입력 -> NFC
- 저장된 데이터 -> NFD
=> 검색 결과가 안 나오는 “유령 버그” 발생 ;;;
자바스크립트에서 안전하게 처리하는 방법 ✅
핵심 원칙
비교하거나 저장하기 전에 정규화하라
String.prototype.normalize()
JS는 유니코드 정규화를 위한 내장 API를 제공한다.
str.normalize("NFC"); str.normalize("NFD");가장 많이 쓰는 패턴 (권장)
const normalize = (str) => str.normalize("NFC"); normalize(a) === normalize(b); // true📌 저장, 비교, 검색 전에 NFC로 통일하는 것이 일반적이다.

정규화 후엔 비교시 제대로 나온다.
언제 어떤 정규화를 써야 할까?
대부분의 웹 서비스 👉 NFC
- 문자열 비교 안정성
- 브라우저 / 서버 / DB 호환성 좋음
- 사용자 입력 처리에 유리
특수한 텍스트 처리 / 언어학적 분석 👉 NFD
- 발음 기호 분리
- 문자 단위 조작
- 조합 문자 분석
실무 체크리스트 🧾
- ✅ 사용자 입력값 normalize
- ✅ 서버 저장 전 normalize
- ✅ 검색/필터 기준 문자열 normalize
- ⚠️ 파일명, slug, key 값은 특히 주의
function safeString(str) { return str.trim().normalize("NFC"); }한 문장으로 요약하면
NFC와 NFD는 “같아 보이지만 다른 문자열”이다. 따라서, 다른 것이 당연.
문자열을 믿지 말고, 정규화를 하여 확실하게 처리하자 🤩참고 자료 📎
- Unicode Normalization (Wikipedia)
https://en.wikipedia.org/wiki/Unicode_equivalence - MDN – String.prototype.normalize
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize - Apple File System and Unicode Normalization
https://developer.apple.com/library/archive/qa/qa1235/_index.html - Unicode Standard Annex #15 (Normalization Forms)
https://unicode.org/reports/tr15/
'기타' 카테고리의 다른 글
HTTPS에서는 지원되나 HTTP에서는 지원되지 않는 기능들 (0) 2026.01.31 FE 개발에서 디버깅 좀 잘해보자 🥺 (1) 2026.01.10 배포 릴리즈 관리, 진짜 알아보기 (Semantic Versioning · 릴리즈 태그 · 배포 자동화 · Semantic-release 완전 안내서) (0) 2026.01.03 jscodeshift로 대규모 코드 리팩토링 자동화하기 🍪 (0) 2025.11.30 깃허브 AI 코드리뷰 자동화 도입기 (PR_AGENT, GEMENI & 무료 ) (1) 2025.11.20