성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
[정성태] The Windows Registry Adventure #1: ...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>유니코드와 한글 - 유니코드와 닷넷을 이용한 한글 처리</h1> <p> 이 글과 관련된 영상을 유튜브로 제공하고 있습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 유니코드와 UTF 인코딩 (4분 영상) ; <a target='tab' href='https://youtu.be/2u6bNtezfoY'>https://youtu.be/2u6bNtezfoY</a> </pre> <br /> <hr style='width: 50%' /> <br /> 유니코드에 대해 잘 정리된 글이 하나 있습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 한글 인코딩의 이해 1편: 한글 인코딩의 역사와 유니코드 ; <a target='tab' href='http://helloworld.naver.com/helloworld/19187'>http://helloworld.naver.com/helloworld/19187</a> </pre> <br /> 2012년 5월호 마이크로소프트웨어 잡지에 보면 위의 글을 쓴 분이 역시 비슷한 내용으로 "유니코드와 한글 - 유니코드와 JAVA를 이용한 한글 처리"라는 글을 쓰셨습니다. (2개의 내용이 다소 다르기 때문에 모두 읽어보셔도 좋습니다. 유니코드 문자셋과 유니코드 인코딩 방식의 차이를 모른다면 꼭 읽어보시길 바랍니다. ^^)<br /> <br /> 위의 글에 보면, JAVA와 한글의 관계가 나오는데요. 저도 ^^ 이와 빗대어서 "유니코드와 한글 - 유니코드와 닷넷을 이용한 한글 처리"를 정리해 보려고 이렇게 글을 쓰는 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <a name='1'></a> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>1. 닷넷의 기본 문자열 인코딩</div> <br /> 일단 자바의 String 개체는 UTF-16 BE 인코딩을 사용한다고 하는데요. 닷넷은 어떨까요? 이에 대해서는 다음의 글에서 찾아볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Character Encoding in the .NET Framework ; <a target='tab' href='https://learn.microsoft.com/ko-kr/dotnet/standard/base-types/character-encoding'>https://learn.microsoft.com/ko-kr/dotnet/standard/base-types/character-encoding</a> </pre> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> <span style='color: blue; font-weight: bold'>UTF-16 encoding is used by the common language runtime</span> to represent Char and String values, and it is used by the Windows operating system to represent WCHAR values. </div><br /> <br /> 즉, 자바와 다른점이라면 UTF-16 BE가 아닌 UTF-16 LE 정도!<br /> <br /> 그 외에 자바의 경우 "<a target='tab' href='http://helloworld.naver.com/helloworld/19187'>한글 인코딩의 이해 1편: 한글 인코딩의 역사와 유니코드</a>"글을 읽다 보면 '변형된 UTF-8'이라는 방식이 나오는데요.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> (자바는) <span style='color: blue; font-weight: bold'>문자열 전송/수신을 위해 직렬화가 필요할 때 변형된 UTF-8(Modified UTF-8)을 사용</span>한다. ... 변형된 UTF-8에서 U+0000을 2바이트로 표시하는 이유는 인코딩된 결과에 널 문자(00)가 나타나지 않게 하고 ... (하는 이유로 U+0000 값이 0xc080 으로 표현된다.) </div><br /> <br /> 애석하게도 제가 자바에 대한 이해도가 낮아 "변형된 UTF-8"이 실제로 사용되는 지에 대한 테스트를 해볼 수는 없었습니다. 단지, String.getBytes에 "UTF-8" 값을 전달하면 "변형된 UTF-8"이 아닌 정상적인 UTF-8 인코딩 된 값이 나오는 것으로 보아,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String string = "\0한글"; String charsetName = "UTF-8"; try { byte [] bytes = string.getBytes(charsetName); for (byte b : bytes) { System.out.print(String.format("0x%02X ", b)); } } catch (UnsupportedEncodingException ex) { } // 출력 결과 - 0x00 값이 0xc080으로 나오지 않기 때문에 '변형된 UTF-8' 인코딩은 아님. 0x00 0xED 0x95 0x9C 0xEA 0xB8 0x80 </pre> <br /> 자바의 내부에서만 특별하게 사용되는 것 같습니다. 닷넷의 경우는, 제가 알기로는 "변형된 UTF-8" 같은 것은 사용하지 않습니다. <br /> <br /> <hr style='width: 50%' /><br /> <a name='2'></a> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>2. 코드 포인트 값 구하기</div> <br /> 자바는 유니코드의 코드 포인트 값을 확인하기 위해 String.codePointAt 메서드를 사용한다고 하는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String string = "\0한글"; for (int i = 0; i < string.length(); i ++) { System.out.print(String.format("U+%04X ", string.codePointAt(i))); } // 출력 결과 U+0000 U+D55C U+AE00 </pre> <br /> 테스트를 해보니 charAt 메서드로 반환된 char 타입이 갖는 값과 동일했습니다. (잠시 후에 설명되지만, 둘의 분명한 차이점이 있습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > for (int i = 0; i < string.length(); i ++) { char ch = string.charAt(i); int chNumber = ch; System.out.print(String.format("0x%02X ", chNumber)); } // 출력 결과 0x00 0xD55C 0xAE00 </pre> <br /> 닷넷의 경우를 확인해 볼까요?<br /> <br /> 우선, string의 메모리 포인터 자체를 반환해서 값을 출력해 보면 자바의 출력 결과와 동일한 코드 포인트 값을 얻게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string text = "\0한글"; fixed (char* ptr = text) { char *pStart = ptr; for (int i = 0; i < text.Length; i++) { int code = *(pStart + i); string txt = string.Format("0x{0:x}", code); Console.WriteLine(txt); } } // 출력 결과 0x0 0xd55c 0xae00 </pre> <br /> 물론, char 타입이 가지고 있는 값도 동일합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > foreach (char a in text) { Console.WriteLine(((int)a).ToString("x")); } // 출력 결과 0x0 0xd55c 0xae00 </pre> <br /> 사실, codePointAt 값과 char 값이 동일한 것은 16비트로 표현되는 유니코드 문자셋에 한해서입니다. 그 이상을 넘어가면 차이를 보입니다. 가령, 16비트를 넘어서는 문자의 예로 0x10000과 0x10001을 들어보겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unicode Character 'LINEAR B SYLLABLE B008 A' (U+10000) ; <a target='tab' href='http://www.fileformat.info/info/unicode/char/10000/index.htm'>http://www.fileformat.info/info/unicode/char/10000/index.htm</a> Unicode Character 'LINEAR B SYLLABLE B038 E' (U+10001) ; <a target='tab' href='http://www.fileformat.info/info/unicode/char/10001/index.htm'>http://www.fileformat.info/info/unicode/char/10001/index.htm</a> </pre> <br /> 위의 글에 따라 0x10000 문자는 "<img alt='unicode_in_net_1.png' src='/SysWebRes/bbs/unicode_in_net_1.png' /> - LINEAR B SYLLABLE B008 A"라는 글자이며 0x10001 문자는 "<img alt='unicode_in_net_2.png' src='/SysWebRes/bbs/unicode_in_net_2.png' /> - LINEAR B SYLLABLE B038 E"라는 글자입니다.<br /> <br /> 이를 자바로 코딩해서 codePointAt을 구하면 다음과 같이 출력 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String string = "\uD800\uDC00\uD800\uDC01"; for (int i = 0; i < string.length(); i ++) { System.out.print(String.format("U+%04X ", string.codePointAt(i))); } // 출력 결과 U+10000 U+DC00 U+10001 U+DC01 </pre> <br /> 이상하군요. 문자열의 크기는 2가 아닌 4로 구해지며 그에 따라 code point값을 출력하는데 0xdc00, 0xdc01 값이 꼭 따라붙게 됩니다. 혹시 0x10000, 0x10001 값만 출력되게 하는 방법이 있을지 모르지만... 어쨌든 그런대로 코드 포인트값이 정확하게 구해지고 있습니다.<br /> <br /> 반면 닷넷의 경우에는 UTF-16 인코딩 된 값만을 가지고 있으므로 다음과 같이 그대로 4바이트의 UTF-16 바이트 값이 출력됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string text = "\uD800\uDC00\uD800\uDC01"; foreach (char a in text) { Console.Write("0x" + ((int)a).ToString("x") + " "); } // 출력 결과 0xd800 0xdc00 0xd800 0xdc01 </pre> <br /> 굳이 2바이트를 넘어가는 유니코드에 대해 코드 포인트 값을 닷넷에서 알고 싶다면 이대로는 안되고, UTF-32로 변형한 후 바이트 배열을 4 바이트씩 끊어서 가져오는 방법을 사용해야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string text = "\uD800\uDC00\uD800\uDC01"; byte[] textBytes = Encoding.UTF32.GetBytes(text); for (int i = 0; i < textBytes.Length / 4; i++) { int codePoint = BitConverter.ToInt32(textBytes, i * 4); Console.Write("0x" + codePoint.ToString("x") + " "); } // 출력 결과 0x10000 0x10001 </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>3. UCS-2와 UTF-16의 차이점</div> <br /> "<a target='tab' href='http://helloworld.naver.com/helloworld/19187'>한글 인코딩의 이해 1편: 한글 인코딩의 역사와 유니코드</a>"글에 보면 다음과 같은 말이 나오는데요.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> 유니코드의 인코딩 방식으로는 <span style='color: blue; font-weight: bold'>코드 포인트를 코드화한 UCS-2와 UCS-4</span>, <span style='color: blue; font-weight: bold'>변환 인코딩 형식(UTF, UCS Transformation Format)</span>인 UTF-7, UTF-8, UTF-16, UTF-32 인코딩 등이 있다. </div><br /> <br /> 그럼, UCS-2와 UTF-16에는 과연 어떤 차이가 있는 걸까요?<br /> <br /> 이에 대해서 검색해 보니, 다음의 글이 나오는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 유니코드의 UCS와 UTF ; <a target='tab' href='http://sweeper.egloos.com/165361'>http://sweeper.egloos.com/165361</a> UTF-16 ; <a target='tab' href='http://ko.wikipedia.org/wiki/UTF-16'>http://ko.wikipedia.org/wiki/UTF-16</a> 국제 문자 세트 ; <a target='tab' href='http://ko.wikipedia.org/wiki/UCS'>http://ko.wikipedia.org/wiki/UCS</a> </pre> <br /> 위의 글을 정리해 보면, UCS-2는 16비트(2바이트)정수를 사용하므로 유니코드 31비트 문자셋 중에서 16비트 이하의 부분만을 표현하도록 되어 있는 반면, UTF-16은 UCS-2를 포함하면서 유니코드 문자셋을 21비트까지 표현할 수 있다는 차이가 있습니다.<br /> <br /> 간단한 예를 들면, 유니코드로 0x1d11e의 값은 UCS-2로는 인코딩이 불가능하지만, UTF-16으로는 0xd834, 0xdd1e로 인코딩하는 것이 가능합니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>4. 닷넷과 한글 인코딩</div> <br /> 그다음, 자바의 String.getBytes 출력 결과를 비교해야 할 필요가 있을 것 같습니다.<br /> <br /> 위에서도 한번 예를 들었지만, String.getBytes에 인코딩 방식을 나타내는 문자열을 전달해 주었는데... 그렇다면 전달하지 않은 경우에는 어떻게 될까요? 영문 윈도우에 한글 설정이 추가된 환경에서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 개발자 PC 환경 - 유니코드(Unicode)를 위한 설정 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/762'>http://www.sysnet.pe.kr/2/0/762</a> </pre> <br /> 다음의 코드를 테스트 해보았습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String string = "\0한글"; byte [] bytes = string.getBytes(); for (byte b : bytes) { System.out.print(String.format("0x%02X ", b)); } // 출력 결과 0x00 0xC7 0xD1 0xB1 0xDB </pre> <br /> 자바의 문서에 보면 "Encodes this {@code String} into a sequence of bytes <span style='color: blue; font-weight: bold'>using the platform's default charset</span>, storing the result into a new byte array." 라고 씌여 있으므로 (영문 윈도우의 기본 인코딩 값이며 닷넷에서는 "Windows-1252"로 알려진) CP1252 인코딩으로 나와야 할텐데, 위의 출력 결과는 그렇지 않습니다. <br /> <br /> 동일한 운영체제에서 닷넷으로 Default 인코딩으로 변환하면 다음과 같은 결과가 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string text = "\u0000한글"; foreach (byte aByte in Encoding.Default.GetBytes(text)) { Console.Write("0x" + aByte.ToString("x") + " "); } // 출력 결과 0x0 0x3f 0x3f </pre> <br /> 0x3f 는 '?' 문자인데, 인코딩 시에 해당 문자값이 없는 경우 대체되는 값으로 일반적인 상황에서 이를 '깨졌다'고 표현합니다. 그리고 이는 Encoding.GetEncoding("Windows-1252").GetBytes를 호출했을 때와 동일한 결과입니다. 그렇다면 (영문 윈도우에 한글이 설치된 경우) 자바가 판단한 "platform's default charset"은 무엇일까요?<br /> <br /> "<a target='tab' href='http://helloworld.naver.com/helloworld/19187'>한글 인코딩의 이해 1편: 한글 인코딩의 역사와 유니코드</a>"글에 보면 다음과 같은 설명이 있는데,<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> <span style='color: blue; font-weight: bold'>EUC-KR은 KS X 1001과 KS X 1003 표준안의 인코딩 방식이며, CP949(MS949, x-windows-949)는 확장 완성형의 인코딩 방식</span>이다. 그러므로 EUC-KR은 2,350자의 한글, CP949는 11,172자의 한글을 표현할 수 있다. 그러나 Java에서는 CP949와 MS949를 다르게 취급한다. CP949는 IBM에서 처음 지정한 코드 페이지(sun.nio.cs.ext.IBM949)가 기준이고 Microsoft가 제정한 확장 완성형은 MS949(sun.nio.cs.ext.MS949)를 기준이다. 그러므로 Java에서는 CP949와 EUC-KR이 사실상 같으며, 확장 완성형을 사용하기 위해서는 MS949로 지정해야 한다. </div><br /> <br /> 여기서 euc-kr과 MS949 방식을 테스트 해볼 필요가 있을 것 같습니다.<br /> <br /> 일단, euc-kr로 테스트 하면 다음과 같이 자바의 기본 getBytes와 동일한 값을 얻을 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string text = "\u0000한글"; foreach (byte aByte in Encoding.GetEncoding("EUC-KR").GetBytes(text)) { Console.Write("0x" + aByte.ToString("x") + " "); } // 출력 결과 0x0 0xc7 0xd1 0xb1 0xdb </pre> <br /> 그렇다면 MS949는 어떻게 지정해야 할까요?<br /> <br /> 제가 예전에 닷넷에서 지원되는 인코딩 방식을 나열했었는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 닷넷에서 지원되는 문자열 인코딩 이름 목록 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1147'>http://www.sysnet.pe.kr/2/0/1147</a> </pre> <br /> 여기 보면, 한글 관련해서 euc-kr과 ks_c_5601-1987이 있는 것을 볼 수 있습니다. 바로 그 "ks_c_5601-1987"이 MS949에 해당합니다. 사실 "ks_c_5601-1987" 이름에 대해서는 논란이 많습니다. 아래의 글에 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 한글 표현에 대한 고찰 ; <a target='tab' href='http://tenny.egloos.com/2598689'>http://tenny.egloos.com/2598689</a> </pre> <br /> MS949라고 마이크로소프트에서 그냥 이름지었으면 되었을 텐데, 이를 euc-kr == "ks_c_5601-1987"로 기존에 사용되던 인코딩 이름을 가져다가 쓴 것이어서 혼란이 왔다는 것입니다.<br /> <br /> 어쨌든, 그렇다면 자바에서 String.getBytes에서 기본 사용한 인코딩 방식이 무엇인지 확인하려면 euc-kr에서는 표현이 안되는 "똠"이라는 글자를 넣어보면 됩니다. 만약 표현이 안되면 euc-kr이고 표현이 되면 MS949 방식인 거죠.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String string = "\0한글똠"; byte [] bytes = string.getBytes(); for (byte b : bytes) { System.out.print(String.format("0x%02X ", b)); } // 출력 결과 0x00 0xC7 0xD1 0xB1 0xDB 0x8C 0x63 </pre> <br /> 보시는 것처럼, 제대로 0x8c, 0x63으로 얻어온 것을 보면 자바의 getBytes에서 "MS949" 방식으로 인코딩 한 것이 맞는 것 같습니다. 그리고, 이와 동일한 결과를 닷넷에서 얻으려면 Microsoft가 차용한 "ks_c_5601-1987"을 "MS949" 대신 지정하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > foreach (byte aByte in Encoding.GetEncoding("ks_c_5601-1987").GetBytes(text)) { Console.Write("0x" + aByte.ToString("x") + " "); } // 출력 결과 0x0 0xc7 0xd1 0xb1 0xdb 0x8c 0x63 </pre> <br /> 정리가 좀 되시나요?<br /> <br /> euc-kr은 2,350 자의 한글 표현이 지원되는 인코딩이고, MS949(윈도우 운영체제에서는 ks_c_5601-1987)는 11,172자의 한글 표현이 가능합니다. 그리고 IBM이 만든 CP949는 닷넷의 문자열 인코딩에는 기본적으로 지원되지 않습니다. euc-kr과 MS949는 코드 체계가 유사하지만 유니코드와는 완전히 다릅니다. 가령 "똠"이라는 글자는 MS949에서는 "0x8c,0x63"이지만 유니코드에서는 "U+b620"에 해당합니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <a name='norm'></a><a name='5'></a> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>5. 유니 코드 정규화</div> <br /> 자바에서 지원되는 Normalizer.normalize 메서드는 닷넷에서도 지원됩니다.<br /> <br /> 자바의 아래와 같은 예제는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String han = "한"; String nfd = Normalizer.normalize(han, Normalizer.Form.NFD); String nfc = Normalizer.normalize(nfd, Normalizer.Form.NFC); </pre> <br /> 닷넷에서 다음과 같이 바뀔 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string han = "한"; string nfd = han.Normalize(NormalizationForm.FormD); // nfd == ㅎ ㅏ ㄴ string nfc = nfd.Normalize(NormalizationForm.FormC); // nfc == 한 <a target='tab' href='https://www.sysnet.pe.kr/2/0/11724#nfd'>NFD (정준 분해) - NormalizationForm.FormD</a> NFC (정준 분해한 뒤 다시 정준 결합) - NormalizationForm.FormC NFKD (호환 분해) - NormalizationForm.FormKD NFKC (호환 분해한 뒤 다시 정준 결합) - NormalizationForm.FormKC </pre> <br /> <hr style='width: 50%' /><br /> <br /> 이 정도면, 닷넷과 유니코드의 관계를 거의 파악한 것 같습니다. 위의 글을 잘 이해하셨다면, 지금쯤 유니코드 및 기타 문자셋들이 눈에 보이실 것입니다. ^^<br /> <br /> 그 외에 닷넷 String과 관련해서 좀 더 자세한 정보는 다음의 문서를 참조하시면 도움이 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > String Class ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.string'>https://learn.microsoft.com/en-us/dotnet/api/system.string</a> </pre> <br /> 특히 위의 글에 포함된 다음의 토픽들이 유니코드와 연관이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Char Objects and Unicode Characters ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.string#Characters'>https://learn.microsoft.com/en-us/dotnet/api/system.string#Characters</a> Normalization ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.string#Normalization'>https://learn.microsoft.com/en-us/dotnet/api/system.string#Normalization</a> </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=726&boardid=331301885'>첨부된 파일은 본문의 내용을 테스트한 예제</a>입니다.)<br /> <br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3569
(왼쪽의 숫자를 입력해야 합니다.)