문서 작업 가이드

시스템 간 텍스트 비교 전에 Unicode 정규화하기

NFC·NFD·NFKC·NFKD를 의도에 맞게 선택하고 코드 포인트·바이트 변화와 호환 손실을 확인한 뒤 대상 시스템에서 결과를 검증합니다.

작성 및 검수 게시일: 검토일:

이 작업 흐름을 검증한 방법

검토에서는 수정하지 않은 “호환 접기 없이 다국어 조회 키 정규화하기” 샘플을 Unicode 정규화에 불러왔습니다. “원본 표현 보존하기”에서 “모든 경고 조사하기”까지의 흐름을 실행해 화면 또는 다운로드 결과를 예시와 비교했습니다. 별도 조사 항목은 “NFKC를 범용 정리로 사용하기”, “숨은 문자가 제거됐다고 가정하기”였습니다.

NFC 결과는 정준 동등한 “Café / 각”이었고 호환 접기가 없음을 보고했으며, 관계없는 전각 문자나 수학 문자는 서로 다른 값으로 유지했습니다.

문제 상황

두 문자열이 똑같이 보여도 코드 포인트 배열이 달라 이진 비교, 파일명, 캐시 키, 가져오기, 경로, 중복 제거가 실패할 수 있습니다. 반대로 무조건 정규화하면 NFKC와 NFKD가 문자 폭, 수학 기호, 표시형, 위첨자, 원문자 같은 의미 있는 구분을 없앨 수 있습니다. 정규화는 잘못된 문자셋으로 디코딩한 바이트를 복구하거나 모든 0폭 문자를 제거하거나 유사 문자 공격을 막지 못하며, 따로 정규화한 조각도 결합 경계에서 다시 비정규화될 수 있습니다. 안전한 절차는 실패한 계층을 먼저 찾고 대상 계약에 맞는 형식을 선택하며 정확한 변경 근거와 실제 대상 테스트를 남깁니다.

공식 출처와 표준

다음 공식 문서는 이 작업 흐름에서 다루는 형식과 보안 경계의 기준입니다. 도구별 실행 검증은 위에 별도로 기록합니다.

이럴 때 사용하세요

  • 겉보기 같은 값이 동등성, 조회, 경로, 캐시, 중복 검사에서 실패할 때
  • 파일명이 macOS, Windows, Linux, 압축 파일, 버전 관리 사이를 이동할 때
  • 악센트·결합 문자·한글 자모가 있는 다국어 레이블을 정규화 규칙이 있는 시스템에 넣을 때
  • 제한된 검색 키에서 전각·반각, 합자, 원문자, 표시형을 의도적으로 접으려 할 때
  • 저장 값을 바꾸기 전에 코드 포인트와 UTF-8 변화 근거가 필요한 마이그레이션을 준비할 때

단계

  1. 1단계

    원본 표현 보존하기

    원본 텍스트를 보관하고 파일에서 가져왔다면 원본 바이트, 파일명, 선언된 인코딩, 디코딩 경로도 남깁니다. U+FFFD 대체 문자나 깨진 글자 패턴은 정규화로 되돌릴 수 없는 이전 디코딩 손실을 뜻할 수 있으므로 먼저 문자셋을 진단합니다.

  2. 2단계

    대상 시스템 계약 확인하기

    데이터베이스, 파일 시스템, 프로토콜, 프로그래밍 언어, 서명, 식별자 정책, 검색 인덱스가 특정 형식을 요구하는지 확인합니다. 웹에서 NFC가 흔하다는 이유만으로 서명 값, 체크섬 입력, 보안 토큰, 외부 명세 식별자를 바꾸지 않습니다.

  3. 3단계

    정준 처리와 호환 처리 선택하기

    정준 동등 배열을 조합해야 하면 NFC, 분해 상태를 유지해야 하면 NFD를 사용합니다. 문자 폭, 합자, 원문자, 위첨자, 표시형을 같은 값으로 취급하는 것이 애플리케이션 정책일 때만 NFKC 또는 NFKD를 선택합니다.

  4. 4단계

    제한된 샘플부터 실행하기

    Unicode 정규화 도구에서 실제 긍정·부정 예시를 먼저 시험합니다. 악센트, 한글, 이모지, 결합 문자, 예상되는 문자 폭 변형, 줄바꿈, 실제 식별자를 포함하고 입력·출력 코드 포인트 수, UTF-8 바이트, 제한된 미리보기를 검토합니다.

  5. 5단계

    모든 경고 조사하기

    호환 접기 경고는 결과가 단순히 다른 정준 표현이 아니라는 뜻입니다. 남은 형식 문자는 별도 검사가 필요하고 U+FFFD가 있으면 가능할 때 원본 바이트를 다시 디코딩해야 합니다. 실행 성공이 이 경고를 무효화하지는 않습니다.

  6. 6단계

    정확한 결과를 비교하고 완성된 값을 정규화하기

    차이 비교 도구와 코드 포인트 근거로 변경된 배열을 모두 확인합니다. 정규화된 문자열도 새 결합 경계에서 다시 조합되거나 순서가 바뀔 수 있으므로 조각을 합친 뒤 실제 비교할 완성 값을 정규화합니다.

  7. 7단계

    저장·조회·왕복 검증하기

    검토한 결과를 실제 데이터베이스, 가져오기 파이프라인, 파일명 작업, 경로 매처, 검색 인덱스의 폐기 가능한 사본에서 시험합니다. 기대한 같음과 다름을 확인하고 저장 바이트를 다시 읽으며, 민감한 원문을 불필요하게 남기지 않고 선택 형식과 테스트 근거를 보관합니다.

예시

호환 접기 없이 다국어 조회 키 정규화하기

입력

원본 코드 포인트: C a f e U+0301 / U+1100 U+1161 U+11A8
대상 계약: NFC
숨은 문자 수: 0
원본 가져오기 바이트를 보관하고 완성된 키를 비교합니다.

출력

결과: Café / 각
정준 동등: 예
호환 접기: 아니요
그다음 대상 인덱스에서 동등성을 시험하고 무관한 전각·수학 문자가 계속 다른 값인지 확인합니다.

흔한 실수

NFKC를 범용 정리로 사용하기

호환 정규화는 수학, 식별자, 타이포그래피, 레거시 왕복, 사용자 표시 내용에서 필요한 구분을 없앨 수 있습니다. 명시적인 동등성 정책이 있는 제한된 필드에만 적용하세요.

디코딩과 정규화를 혼동하기

잘못된 문자셋 디코딩은 정규화가 시작되기 전에 정보를 바꾸거나 잃습니다. 깨진 글자와 U+FFFD를 반복 정규화하지 말고 원본 바이트를 보존해 다시 디코딩하세요.

숨은 문자가 제거됐다고 가정하기

Unicode 정규화는 보통 0폭 문자와 형식 문자를 유지합니다. 남은 개수를 확인하고 어떤 문자가 잘못됐는지 결정한 뒤 전용 제거 절차를 사용하세요.

각 조각을 한 번만 정규화하기

새 결합 경계에서 조합 가능 배열이나 결합 문자 재정렬이 생길 수 있습니다. 실제 저장·비교할 완성된 값을 다시 정규화하세요.

정준 동등성을 애플리케이션 동등성으로 간주하기

애플리케이션은 정규화 외에도 로케일 정렬, 대소문자 접기, 보안 프로필, 정확한 바이트 동일성을 사용할 수 있습니다. 한 번의 정규화 결과로 추정하지 말고 대상 동작을 시험하세요.

자주 묻는 질문

겉보기 같은 문자열의 바이트가 왜 다를 수 있나요?

Unicode는 일부 추상 문자를 하나의 조합 문자 또는 기본 문자와 결합 문자 배열로 표현할 수 있습니다. 화면은 같아도 이진 비교 결과는 다를 수 있습니다.

일반적인 웹 텍스트에는 어떤 형식이 가장 안전한가요?

NFC가 웹 상호 운용에 널리 권장되지만 최종 기준은 대상 계약입니다. 원본 근거를 보관하고 서명·식별자·프로토콜 필드에는 규칙 확인 없이 기본값을 적용하지 마세요.

NFKC는 언제 적절한가요?

호환 변형을 같은 값으로 비교하도록 명시한 제한된 검색 또는 식별자 프로필에는 적절할 수 있습니다. 임의의 문장이나 수학적 의미가 있는 내용을 자동으로 다시 쓰는 용도에는 적절하지 않습니다.

정규화하면 유사 문자 공격도 막을 수 있나요?

아닙니다. 서로 다른 문자 체계의 유사 문자는 정규화 후에도 남을 수 있습니다. 보안 식별자에는 적절한 Unicode 보안 프로필, 문자 체계 정책, 애플리케이션 검토가 필요합니다.

왜 문자열을 합친 뒤 다시 정규화해야 하나요?

Unicode 정규화 형식은 문자열 결합에 대해 닫혀 있지 않습니다. 새 경계의 문자가 조합되거나 결합 문자 순서가 달라질 수 있어 최종 값을 정규화해야 합니다.

이 절차만으로 마이그레이션 안전성을 증명할 수 있나요?

로컬 변환과 정확한 근거는 제공하지만 안전성은 대상의 비교, 인덱싱, 고유성, 서명, 왕복 동작에도 달려 있습니다. 되돌릴 수 있는 계획과 함께 해당 시스템을 시험하세요.