grad.egloos.com

Rising 炫

포토로그 방명록



Google Adsense


[,NET] 한글 문자열을 2바이트로 계산하여 길이를 자르기 Tip & Know-how

문제에 대해 먼저 다시 한 번 요약을 하자면, 모든 문자를 유니코드로 처리하는 닷넷 프레임워크상에서 한글 문자열을 2바이트로 처리해서 원하는 바이트 길이만큼 자르는 방식이 필요하다는 것입니다.

하늘이님이 위와 같은 문제를 올려주셨더군요. @_@;;; 저도 닷넷을 공부하는지라 열심히 찾아보았는데, 데브피아 게시판의 글(질문글/답변글)을 참고하여 해결할 수 있었습니다.

우선 해결하는 법을 먼저 말하면 Encoding으로 "ks_c_5601-1987"을 사용하면 됩니다.

예제 코드는 아래와 같습니다. 아래 코드는 c#으로 작성되어 있습니다만, 하늘이님의 말처럼 닷넷 개발자분들이라면, 이미 C# 소스와 VB.NET 소스 정도는 왔다갔다 하면서 이해하는건 익숙해지셨을꺼라 믿습니다. ^^;

private string getWordByByte( string src, int byteCount )
{
       System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding("ks_c_5601-1987");

       byte[] buf = myEncoding.GetBytes( src );

       return myEncoding.GetString( buf, 0, byteCount );
}

다음과 같이 테스트를 해보죠.
string txtKor = "가나다라마";
string txtEng = "abcde";

Console.WriteLine( getWordByByte( txtKor, 5 ) );
Console.WriteLine( getWordByByte( txtEng, 5 ) );

위 코드의 실행 결과는 아래와 같습니다.
가나
abcde

만약, byteCount를 5로 했을때 한글 3글자를 얻어오고 싶다면 함수 부분을 다음과 같이 수정해 주면 됩니다.

private string getWordByByte( string src, int byteCount )
{
       System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding("ks_c_5601-1987");

       byte[] buf = myEncoding.GetBytes( src );

       string result = myEncoding.GetString( buf, 0, byteCount );

       if( byteCount != result.Length )
       {
              result = myEncoding.GetString( buf, 0, byteCount+1 );
       }


       return result;
}

resultKor과 resultEng의 Length 값을 찍어보면 3, 5로 다르기 때문에 위와 같은 방법으로 한글인지 영문인지도 구분할 수가 있습니다.

부연 설명
유니코드 인코딩으로 GetBytes를 해보면 한글이나 영문이나 배열을 2칸씩 사용하면서 정보가 들어갑니다. 그러나 영문은 1 byte이기 때문에 2번째 칸에는 무조건 0이란 값만 들어가게 됩니다. 필요없는 데이터가 함께 들어가더군요.

아스키 인코딩으로 해보면 한글을 인식하지 못하기 때문에 한글 정보가 제대로 들어가지 않습니다. 한글을 1바이트 안에 넣으려고 하죠.

하지만 위에서 사용한 인코딩 방법은 한글은 배열을 2칸씩, 영문은 1칸씩 사용하면서 넣어줍니다. 덕분에 문자열이 한글이든 영문이든 바이트 단위로 잘 가져올 수 있더군요.

하늘이님 덕분에 저도 좋은 공부했네요. ^^

덧글

  • 하늘이 2005/02/01 17:10 # 삭제

    헤헤~ 우선 제가 이러한 변환식을 꼭 루프로 이용했던 이유가 있었습니다만, 바로 영문과 한글이 섞여있는 경우와, 한글에서 5바이트를 얻어오는 경우 쓰레기 문자 1바이트가 포함되는걸 없애기 위함이었습니다만.

    쓰레기 문자는 아시리라 믿고요. ^^; 2번째 소스코드의 문제는 아래와 같은 문자열을 5바이트로 짤라보시면 아실 수 있을것이라 믿습니다.

    "가나ABCDE" -> 5바이트로 짜를때 -> "가나AB"

    String 객체의 length로 길이를 비교하셨는데, 역시 length는 유니코드로 계산해버리기 때문에 이러한 문제가 생겨버리네요. ^^;
  • 그라드 2005/02/01 19:32 #

    * 하늘이: 그렇군요. 그런 문제가...@_@;; 좀 더 연구해 봐야 겠군요. ㅎㅎ
  • CN 2005/03/11 21:49 # 삭제

    USC-2로 인코딩하나 보군요.
  • 그라드 2005/03/11 22:13 #

    * CN: 전 여기까지만 진행했어요. 조금씩 추가하다 보면 하늘이님의 소스와 많이 비슷할 것 같아서 ^^;
  • 램프바바 2007/06/07 11:27 # 삭제

    위의 방법대로 하면 공백도 2바이트로 처리되는것 같습니다.
    공백은 1바이트로 처리되는게 맞을듯 싶네요.^^;
  • 그라드 2007/06/07 14:17 #

    * 램프바바님 // 음 그런가요? 요건에 따라 유용하게 쓸 수는 있겠네요 ^^;
  • hoi.kwak 2012/05/24 14:24 # 삭제

    좋은 정보 감사합니다.유용한 정보 공유해주셔서 제 블로그에 공유해갑니다.
  • 오들 2012/07/31 15:36 # 삭제

    if( byteCount != result.Length )
    -> if( byteCount != myEncoding.GetBytes(result).length )
    로 하니 잘 되네요.
    소스 감사합니다.
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.