1) 한글 문자 생성기

먼저 한글 문자 생성기를 정적 클래스 KoreanCharMaker로 정의합시다.

public static class KoreanCharMaker
{

먼저 한글 문자가 시작하는 BASE CODE(0xAC00), 초성 시작점(0x1100), 중성 시작점(0x1161)을 상수로 선언합니다.

    const int BASE_CODE = 0xAC00;

    const int BASE_INIT = 0x1100;

    const int BASE_VOWEL = 0x1161;

한글과 관련있는 자판 문자를 초성, 중성, 종성과 쉬프트 키를 정적 문자열로 선언합니다.

//한글 코드 값 = 초성*중성개수*종성 개수+중성 *종성개수+종성+BASE 코드(0xAC00)
    const int BASE_CODE = 0xAC00;//BASE 코드
    const int BASE_INIT = 0x1100; //'ㄱ'
    const int BASE_VOWEL = 0x1161; //'ㅏ'
    static string chostring = "rRseEfaqQtTdwWczxvg";//초성에 사용하는 키 목록
    static string chostring_k = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";//한글 초성

중성과 종성은 이중 문자로 구성하는 것들이 있어 문자열 목록을 정의해야 합니다. 이 부분은 정적 생성자에서 초기화합시다.

    static string[] jungstrs = null;//중성에 사용하는 문자열 목록
    static string[] jungstrs_k = null;//한글 중성
    static string[] jongstrs = null;//종성에 사용하는 문자열 목록
    static string[] jongstrs_k = null;//한글 종성

정적 생성자에서 중성과 종성에 사용하는 문자열 목록을 생성및 초기화합시다.

    static KoreanCharMaker()
    {
        jungstrs = new string[] { "k", "o", "i", "O", "j", "p", "u", "P", "h", "hk", "ho", "hl", "y", "n", "nj", "np", "nl", "b", "m", "ml", "l" };
        jungstrs_k = new string[] { "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ" };
        jongstrs = new string[] { string.Empty, "r", "R", "rt", "s", "sw", "sg", "e", "f", "fr", "fa", "fq", "ft", "fx", "fv", "fg", "a", "q", "qt", "t", "T", "d", "w", "c", "z", "x", "v", "g" };
        jongstrs_k = new string[] { string.Empty, "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" };
    }

초성의 자판 문자를 입력인자로 받아 초성 코드를 반환하는 메서드를 정의합시다.

    public static int GetInitSoundCode(char ch)
    {

입력 인자로 들어온 문자가 초성 문자열의 몇 번째 문자인지 반환합니다. 입력 인자가 한글 초성 문자가 올 수도 있고 한글 초정과 매핑하는 영어 알파벳이 올 수 있습니다. 먼저 한글 초성 목록에서의 index를 계산합니다.

        int index = chostring_k.IndexOf(ch);

만약 index가 -1이 아니면 한글 초성이 입력 인자로 온 것이므로 index를 반환합니다.

        if (index != -1){    return index;    }

index가 -1이면 한글 초성과 매핑하는 영어 알파벳 목록에서의 index를 반환합니다.

        return chostring.IndexOf(ch);
    }

같은 방법으로 중성 문자열을 입력인자로 받아 중성 코드를 반환하는 메서드를 만듭시다. 중성은 이중 모음으로 만들 수도 있기 때문에 문자열을 입력인자로 받게 합시다.

    public static int GetVowelCode(string str)
    {
        int cnt = jungstrs.Length;
        for (int i = 0; i < cnt; i++)
        {
            if (jungstrs[i] == str){    return i;    }
        }
        for (int i = 0; i < cnt; i++)
        {
            if (jungstrs_k[i] == str){    return i;    }
        }
        return -1;
    }

입력 인자로 한글 중성 문자나 한글 중성 문자와 매핑하는 영어 알파벳을 입력인자로 받을 때도 처리할 수 있는 메서드를 정의합시다. 여기서는 앞에서 만든 메서드를 이용합니다. 이처럼 같은 일을 하는 메서드를 중복 정의하는 이유는 사용하는 개발자의 편의성을 높이기 위해서입니다.

    public static int GetVowelCode(char ch)
    {
        return GetVowelCode(ch.ToString());
    }

같은 방법으로 종성 문자열을 입력인자로 받아 중성 코드를 반환하는 메서드를 만듭시다.

    public static int GetFinalConsonantCode(string str)
    {
        int cnt = jongstrs.Length;
        for (int i = 0; i < cnt; i++)
        {
            if (jongstrs[i] == str){    return i;    }
        }
        for (int i = 0; i < cnt; i++)
        {
            if (jongstrs_k[i] == str){    return i;    }
        }
        return -1;
    }

    public static int GetFinalConsonantCode(char ch)
    {
        return GetFinalConsonantCode(ch.ToString());
    }

자음 하나로 만들어진 한글 문자를 만드는 메서드를 정의합시다.

    public static char GetSingleJa(int value)
    {
        byte[] bytes = BitConverter.GetBytes((short)(BASE_INIT + value));
        return Char.Parse(Encoding.Unicode.GetString(bytes));
    }

모음 하나로 만들어진 한글 문자를 만드는 메서드를 정의합시다.

    public static char GetSingleVowel(int value)
    {
        byte[] bytes = BitConverter.GetBytes((short)(BASE_VOWEL + value));
        return Char.Parse(Encoding.Unicode.GetString(bytes));
    }

초성, 중성, 종성으로 만들어진 한글 문자를 만드는 메서드를 정의합시다.

    public static char GetCompleteChar(int init_sound, int vowel, int final)
    {
        int tempFinalConsonant = 0;
        if (final >= 0){    tempFinalConsonant = final;    }
        int jungcnt = jungstrs.Length;
        int jongcnt = jongstrs.Length;
        int completeChar = init_sound * jungcnt * jongcnt +
                           vowel * jongcnt + tempFinalConsonant + BASE_CODE;
        byte[] naeBytes = BitConverter.GetBytes((short)(completeChar));
        return Char.Parse(Encoding.Unicode.GetString(naeBytes));
    }

이제 Program 클래스의 진입점 Main 메서드에서 테스트하는 코드를 작성합시다.

여기에서는 언제나휴일을 만들는 테스트를 합시다. 언제나는 한글 자모로 구성하기로 하고 휴일은 영어 알파벳 문자로 구성하기로 합시다. 그리고 테스트 하기 쉽게 초성, 중성, 종성을 입력 인자로 전달하면 한 개의 한글을 만드는 메서드를 정의하여 이용하기로 합시다.

private static void ViewHangul(char ic, char vc, char fc)
{

입력 인자로 받은 초성과 중성, 종성의 코드 값을 구합니다.

    int init = KoreanCharMaker.GetInitSoundCode(ic);
    int vowel = KoreanCharMaker.GetVowelCode(vc);
    int final = KoreanCharMaker.GetFinalConsonantCode(fc);

그리고 총성과 중성, 종성의 코드 값을 입력 인자로 한글 문자를 만듭니다.

    char kch = KoreanCharMaker.GetCompleteChar(init, vowel, final);

만든 한글 문자를 콘솔에 출력합니다.

    Console.Write(kch.ToString());
}
static void Main(string[] args)

{

언제나 부분은 한글 자음과 모음을 이용해서 만들고 휴일 부분은 한글 자음, 모음과 매핑하는 영어 알파벳 문자를 이용해서 만들기로 합시다.

    ViewHangul('ㅇ', 'ㅓ', 'ㄴ');
    ViewHangul('ㅈ', 'ㅔ' ,char.MinValue);
    ViewHangul('ㄴ', 'ㅏ',char.MinValue);
    ViewHangul('g', 'b',char.MinValue);
    ViewHangul('d', 'l','f');
    Console.WriteLine();
    Console.ReadKey();
}
using System;
using System.Text;

namespace 한글문자_생성기
{
    public static class KoreanCharMaker
    {
        //한글 코드 값 = 초성*중성개수*종성 개수+중성 *종성개수+종성+BASE 코드(0xAC00)
        const int BASE_CODE = 0xAC00;//BASE 코드
        const int BASE_INIT = 0x1100; //'ㄱ' 
        const int BASE_VOWEL = 0x1161; //'ㅏ'        
        static string chostring = "rRseEfaqQtTdwWczxvg";//초성에 사용하는 키 목록

        static string chostring_k = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";//한글 초성
        static string[] jungstrs = null;//중성에 사용하는 문자열 목록
        static string[] jungstrs_k = null;//한글 중성 
        
        static string[] jongstrs = null;//종성에 사용하는 문자열 목록
        static string[] jongstrs_k = null;//한글 종성

        static KoreanCharMaker()
        {
            jungstrs = new string[] { "k", "o", "i", "O", "j", "p", "u", "P", "h", "hk", "ho", "hl", "y", "n", "nj", "np", "nl", "b", "m", "ml", "l" };
            jungstrs_k = new string[] { "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ" };
            jongstrs = new string[] { string.Empty, "r", "R", "rt", "s", "sw", "sg", "e", "f", "fr", "fa", "fq", "ft", "fx", "fv", "fg", "a", "q", "qt", "t", "T", "d", "w", "c", "z", "x", "v", "g" };
            jongstrs_k = new string[] { string.Empty, "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ" };
        }
        public static int GetInitSoundCode(char ch)
        {
            int index = chostring_k.IndexOf(ch);
            if (index != -1){    return index;    }
            return chostring.IndexOf(ch);
        }
        public static int GetVowelCode(string str)
        {
            int cnt = jungstrs.Length;
            for (int i = 0; i < cnt; i++)
            {
                if (jungstrs[i] == str){    return i;    }
            }
            for (int i = 0; i < cnt; i++)
            {
                if (jungstrs_k[i] == str){    return i;    }
            }
            return -1;
        }

        public static int GetVowelCode(char ch)
        {
            return GetVowelCode(ch.ToString());
        }

        public static int GetFinalConsonantCode(string str)
        {
            int cnt = jongstrs.Length;
            for (int i = 0; i < cnt; i++)
            {
                if (jongstrs[i] == str){    return i;    }
            }
            for (int i = 0; i < cnt; i++)
            {
                if (jongstrs_k[i] == str){    return i;    }
            }
            return -1;
        }

        public static int GetFinalConsonantCode(char ch)
        {
            return GetFinalConsonantCode(ch.ToString());
        }

        public static char GetSingleJa(int value)
        {
            byte[] bytes = BitConverter.GetBytes((short)(BASE_INIT + value));
            return Char.Parse(Encoding.Unicode.GetString(bytes));
        }

        public static char GetSingleVowel(int value)
        {
            byte[] bytes = BitConverter.GetBytes((short)(BASE_VOWEL + value));
            return Char.Parse(Encoding.Unicode.GetString(bytes));
        }

        public static char GetCompleteChar(int init_sound, int vowel, int final)
        {
            int tempFinalConsonant = 0;
            if (final >= 0)
            {
                tempFinalConsonant = final;
            }

            int jungcnt = jungstrs.Length;
            int jongcnt = jongstrs.Length;
            int completeChar = init_sound * jungcnt * jongcnt + vowel * jongcnt 
                               + tempFinalConsonant + BASE_CODE;
            byte[] naeBytes = BitConverter.GetBytes((short)(completeChar));
            return Char.Parse(Encoding.Unicode.GetString(naeBytes));
        }
    }
}

[소스 8.5] KoreanCharMaker.cs

using System;

namespace 한글문자_생성기
{
    class Program
    {
        private static void ViewHangul(char ic, char vc, char fc)
        {
            int init = KoreanCharMaker.GetInitSoundCode(ic);
            int vowel = KoreanCharMaker.GetVowelCode(vc);
            int final = KoreanCharMaker.GetFinalConsonantCode(fc);
            char kch = KoreanCharMaker.GetCompleteChar(init, vowel, final);
            Console.Write(kch.ToString());
        }
        static void Main(string[] args)
        {
            ViewHangul('ㅇ', 'ㅓ', 'ㄴ');
            ViewHangul('ㅈ', 'ㅔ' ,char.MinValue);
            ViewHangul('ㄴ', 'ㅏ',char.MinValue);
            ViewHangul('g', 'b',char.MinValue);
            ViewHangul('d', 'l','f');
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

[소스 8.6] Program.cs

[그림 8.04] 실행화면