유니코드 정규화를 사용하여 문자열 표시
애플리케이션은 유니코드를 사용하여 여러 형식의 문자열을 나타낼 수 있습니다. 특히 인터넷을 통해 유니코드 수용이 증가함에 따라 유니코드 문자열의 필수적이지 않은 차이를 제거해야 합니다. 예를 들어 웹 서버가 페이지 요청에 응답하거나 링커가 라이브러리에서 특정 식별자를 찾는 경우와 같이 문자 조합에 대한 여러 표현은 소프트웨어를 복잡하게 만듭니다.
주의
다른 유니코드 문자열은 시각적으로 동일한 것처럼 보일 수 있으므로 보안 문제가 제기됩니다. 자세한 내용은 보안 고려 사항: 국가별 기능을 참조하세요.
이 요구 사항에 따라 유니코드 컨소시엄은 문자의 해당하는 이진 표현에 대해 하나의 이진 표현을 생성하는 "정규화"라는 프로세스를 정의했습니다. 정규화되면 두 문자열은 동일한 이진 표현이 있는 경우에만 동일합니다. 정규화는 몇 가지 차이점을 제거하지만 대/소문자를 유지합니다.
유니코드 정규화를 사용하기 위해 애플리케이션은 유니코드 4.0 TR#15로의 문자열 다시 정렬을 위해 NormalizeString 및 IsNormalizedString 함수를 호출할 수 있습니다. 정규화는 언어적 의미가 동일한 대체 문자열 표현을 줄여 보안을 개선하는 데 도움이 될 수 있습니다. 그러나 정규화는 대체 표현을 완전히 제거할 수 없습니다.
정규화를 위한 유니코드 표준에 대한 자세한 설명은 유니코드 표준 부속서 #15: 유니코드 정규화 양식 (UAX #15)을 참조하세요.
주의
정규화는 문자열의 형식을 변경할 수 있으므로 일반적으로 정규화 후에 보안 메커니즘 또는 문자 유효성 검사 알고리즘을 구현해야 합니다. 자세한 내용은 보안 고려 사항: 국가별 기능을 참조하세요.
동일한 문자열의 여러 표현 제공
대부분의 경우 유니코드는 언어적으로 동일한 문자열에 대한 여러 표현을 허용합니다. 예:
- dieresis(umlaut)가 있는 대문자 A는 단일 유니코드 코드 포인트 "Ä"(U+00C4) 또는 Capital A와 결합된 Dieresis 문자("A" + " ", 즉 U+0041 U+0308)의 조합으로 나타낼 수 있습니다. 분음 부호가 있는 다른 많은 문자에서도 비슷한 고려 사항이 적용됩니다.
- 대문자 A 자체는 일반적인 방식(라틴어 대문자 A, U+0041) 또는 Fullwidth Latin Capital Letter A(U+FF21)로 나타낼 수 있습니다. 다른 간단한 라틴 문자(대문자와 소문자 모두)와 일본어 쓰기에 사용되는 가타카나 문자에도 비슷한 고려 사항이 적용됩니다.
- 문자열 "fi"는 문자 "f" 및 "i"(U+0066 U+0069) 또는 합자 "fi"(U+FB01)로 나타낼 수 있습니다. 유니코드가 합자를 정의하는 다른 많은 문자 조합에 에서도 비슷한 고려 사항이 적용됩니다.
4개의 정의된 정규화 양식 사용
애플리케이션은 다른 규칙을 준수하는 "정규화 양식"이라는 여러 알고리즘을 사용하여 유니코드 정규화를 수행할 수 있습니다. 유니코드 컨소시엄은 NFC(양식 C), NFD(양식 D), NFKC(양식 KC) 및 NFKD(양식 KD)의 네 가지 정규화 양식을 정의했습니다. 각 양식은 몇 가지 차이점을 제거하지만 대/소문자를 유지합니다. Win32 및 .NET Framework 네 가지 정규화 양식을 모두 지원합니다.
NLS 열거형 형식 NORM_FORM 네 가지 표준 유니코드 정규화 양식을 지원합니다. 양식 C 및 D는 문자열에 대한 정식 양식을 제공합니다. 비 정식 양식 KC 및 KD는 추가 호환성을 제공하며 C 및 D 양식에서 명확하지 않은 특정 의미 체계 동등성을 표시할 수 있습니다. 그러나 특정 정보 손실을 희생하여 이 작업을 수행하며 일반적으로 문자열을 저장하는 정식 방법으로 사용하면 안 됩니다.
두 정식 양식 중 C형식은 "구성된" 양식이고 D형식은 "분해된" 양식입니다. 예를 들어 C 양식은 단일 유니코드 코드 포인트 "Ä"(U+00C4)를 사용하고 양식 D는 ("A" + "", 즉 U+0041 U+0308)를 사용합니다. " 0308(U+0308)은 결합 문자이므로 이러한 렌더링은 동일하게 렌더링됩니다. 양식 D는 임의의 수의 코드 포인트를 사용하여 C 양식에서 사용하는 단일 코드 포인트를 나타낼 수 있습니다.
두 문자열이 C 또는 양식 D 형식으로 동일한 경우 다른 형식에서 동일합니다. 또한 올바르게 렌더링되면 서로 구별할 수 없이 표시되고 원래 정규화되지 않은 문자열에서 표시됩니다.
정규화되면 문자열을 원래 표현으로 일관되게 반환할 수 없습니다. 예를 들어 구성 및 분해된 문자 표현이 혼합된 문자열이 정규화된 형식으로 변환되는 경우 원래 혼합 문자열로 정규화 해제할 방법이 없습니다. 따라서 애플리케이션에 문자열의 원래 표현이 필요한 경우 해당 표현을 명시적으로 저장해야 합니다. 그러나 두 정식 양식 간 변환은 되돌릴 수 있습니다. C 형식의 문자열을 양식 D로 변환한 다음 C 형식으로 다시 변환할 수 있으며 결과는 원래 형식 C 문자열과 동일합니다.
양식 KC 및 KD는 각각 C 및 D 양식과 유사하지만 이러한 "호환성 양식"에는 각 문자의 기본 형식과 호환되는 문자의 추가 매핑이 있습니다. 이러한 매핑으로 인해 사소한 문자 변형이 손실될 수 있습니다. 시각적으로 고유한 특정 문자를 결합합니다. 예를 들어 전체 너비와 반자 문자를 동일한 의미 체계 또는 동일한 아랍어 문자의 다른 형식 또는 합자 "fi"(U+FB01) 및 문자 쌍 "fi"(U+0066 U+0069)와 결합합니다. 또한 위 첨자로 작성된 숫자, 아래 첨자 또는 원으로 묶인 숫자와 같이 의미 체계가 다를 수 있는 일부 문자를 결합합니다. 이러한 정보 손실로 인해 양식 KC 및 KD는 일반적으로 정식 문자열 형식으로 사용해서는 안 되지만 특정 애플리케이션에 유용합니다.
양식 KC는 구성된 양식이며 양식 KD는 분해된 양식입니다. 애플리케이션은 양식 KC와 KD 간에 앞뒤로 이동할 수 있지만 원래 문자열이 C 또는 D 형식인 경우에도 양식 KC 또는 KD에서 원래 문자열로 다시 이동하는 일관된 방법은 없습니다.
Windows, Microsoft 애플리케이션 및 .NET Framework 일반적으로 일반 입력 메서드를 사용하여 C 형식의 문자를 생성합니다. Windows에서 대부분의 용도로 C 양식이 기본 설정 양식입니다. 예를 들어 C 형식의 문자는 Windows 키보드 입력에 의해 생성됩니다. 그러나 웹 및 기타 플랫폼에서 가져온 문자는 데이터 스트림에 다른 정규화 양식을 도입할 수 있습니다.
다음 예제는 UAX #15에서 가져온 것이며 네 가지 정규화 양식 간의 차이점을 보여 줍니다.
Original | 양식 D | 양식 C | 참고 |
---|---|---|---|
"Äffin" | "A\u0308ffin" | "Äffin" | ffi_ligature(U+FB03)은 정식 매핑이 아닌 호환성 매핑을 가지고 있기 때문에 분해되지 않습니다.${REMOVE}$ |
"Ä\uFB03n" | "A\u0308\uFB03n" | "Ä\uFB03n" | |
"Henry IV" | "Henry IV" | "Henry IV" | 로마 숫자 IV(U+2163)가 분해되지 않았습니다.${REMOVE}$ |
"Henry \u2163" | "Henry \u2163" | "Henry \u2163" | |
ga | ka +10 | ga | 단일 일본어 문자에 해당하는 호환성이 다르면 C.${REMOVE}$ 형식으로 동일한 문자열이 생성되지 않습니다. |
ka +10 | ka +10 | ga | |
hw_ka +hw_ten | hw_ka +hw_ten | hw_ka +hw_ten | |
ka +hw_ten | ka +hw_ten | ka +hw_ten | |
hw_ka +10 | hw_ka +10 | hw_ka +10 | |
kaks | k i + a m + ks f | kaks | 한글 음절은 정규화에서 유지됩니다. |
Original | 양식 KD | 양식 KC | 참고 |
---|---|---|---|
"Äffin" | "A\u0308ffin" | "Äffin" | ffi_ligature(U+FB03)은 KC 형식으로 분해되지만 C.${REMOVE}$ 형식은 아닙니다. |
"Ä\uFB03n" | "A\u0308ffin" | "Äffin" | |
"Henry IV" | "Henry IV" | "Henry IV" | 결과 문자열은 KC.${REMOVE}$ 형식으로 동일합니다. |
"Henry \u2163" | "Henry IV" | "Henry IV" | |
ga | ka +10 | ga | 단일 일본어 문자에 해당하는 호환성이 다르면 KC.${REMOVE}$ 형식으로 동일한 문자열이 생성됩니다. |
ka +10 | ka +10 | ga | |
hw_ka +hw_ten | ka +10 | ga | |
ka +hw_ten | ka +10 | ga | |
hw_ka +10 | ka +10 | ga | |
kaks | k i + a m + ks f | kaks | 한글 음절은 정규화에서 유지됩니다. 이전 유니코드 버전에서는 ks f 와 같은 jamo 문자에 k f + s f에 대한 호환성 매핑이 있었습니다. 이러한 매핑은 한글 음절이 유지되도록 유니코드 2.1.9에서 제거되었습니다. |
참고
위의 두 테이블에는 1998-2006 유니코드, Inc.의 © 저작권이 있습니다. 판권.
단일 문자 모양에 Composed Forms 사용
단일 문자 모양에 해당하는 많은 문자 시퀀스에는 구성된 양식이 없습니다. C 형식으로 정규화된 경우에도 단일 시각적 문자 모양 또는 논리 텍스트 요소는 여러 유니코드 코드 포인트로 구성될 수 있습니다. 예를 들어 리투아니아어 쓰기에 사용되는 여러 문자는 분해된 양식만 있으므로 이중 분음 부호가 있습니다. 예를 들어, 마크론과 타일이 있는 소문자 U("으로움", U+016b U+0303)가 있습니다. 여기서 첫 번째 코드 포인트는 마크론이 있는 소문자 U이고 두 번째는 급성 악센트를 결합하는 것입니다.
예제
관련 예제는 NLS: 유니코드 정규화 샘플에서 찾을 수 있습니다.
관련 항목