ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NFC / NFD란 무엇이고, 왜 문자열 이슈를 만든 걸까 ⁉️
    기타 2026. 2. 4. 06:42

    웹이나 앱에서 문자열을 다루다 보면 가끔 이런 이상한 상황을 만난다.

    • 화면에 똑같이 보이는데 문자열 비교가 실패함
    • 파일명이 같아 보이는데 OS마다 다르게 취급됨
    • 검색이 안 되거나, 중복 체크가 통과됨

    이 문제의 원인은 종종 유니코드 정규화(Normalization), 그중에서도 NFC와 NFD의 차이에 있다.

     

    유니코드 정규화란?

    유니코드는 같은 글자를 여러 방식으로 표현할 수 있다.

    예를 들어 é는 다음 두 가지 방식으로 표현 가능하다.

    1️⃣ NFC (Normalization Form C)

    • 하나의 코드 포인트로 결합된 형태
    é  → U+00E9

    2️⃣ 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; // false

    UI에서는 동일해 보이는데, 로직에서는 다른 값으로 인식된다.

     

     

    콘솔로 실제 찍어보면 ??

     

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

     

    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는 “같아 보이지만 다른 문자열”이다. 따라서, 다른 것이 당연.
    문자열을 믿지 말고, 정규화를 하여 확실하게 처리하자 🤩

    참고 자료 📎

     

Designed by Tistory.