#keywords utf-8,utf8,unicode,ks5601,hangul,한글,오토마타,10벌,9벌,bitmap,font,조합형,완성형,cp949,euckr,composite,code,ucs,iconv #title 조합형 한글 [wiki:Home 대문] / [wiki:CategoryProgramming 프로그래밍] / [wiki:CompositeHangul 조합형 한글] ---- == [wiki:CompositeHangul 조합형 한글] == * 작성자 조재혁([mailto:minzkn@minzkn.com]) * 고친과정 2003년 9월 22일 : 처음씀[[br]] 2014년 9월 10일 : Unicode 호환자모(U+3131~) 영역에 대한 내용 추가 [[TablEOfContents]] == 조합형 한글의 특징 == * 한글의 효율적인 오토마타개발이나 폰트의 최소화를 위해서 노력하는것이 당연하다고 생각하신다면 맞을겁니다. * 완성형 코드는 입력기의 개발에 많은 테이블을 소요하지만 조합형은 테이블의 크기가 작은 상태에서 개발이 가능합니다. * 옛 조합형은 Unicode 로 대체가 가능하고 Unicode가 훨씬 다양한 조합력을 나타낼수 있기 때문에 이제는 거의 사라져 가는 추세입니다. == 옛 조합형 코드표 (조합형: 삼보, 대우, 현대, 쌍용, 큐닉스) == * 일부 조합형을 독자적으로 개발하거나 개선된 코드변환을 위해서 미정의상태를 채움으로 처리해야 하는 경우가 있습니다. * 오래된 구어표시영역이 있으나 필자의 자료는 그 부분에 대해서는 충분히 열거할수 없기에 표시하지 않겠습니다. |옛 조합형 코드표| 비트조합 (bit) || 10진 코드 || 16진 코드 || 초성(순번) || 중성(순번) || 종성(순번) || || 0 0 0 0 0 || 0 || 00 || 미정의 || 미정의 || 미정의 || || 0 0 0 0 1 || 1 || 01 || 채움 || 미정의 || 채움 || || 0 0 0 1 0 || 2 || 02 || ㄱ (0x00) || 채움 || ㄱ (0x00) || || 0 0 0 1 1 || 3 || 03 || ㄲ (0x01) || ㅏ (0x00) || ㄲ (0x01) || || 0 0 1 0 0 || 4 || 04 || ㄴ (0x02) || ㅐ (0x01) || ㄳ (0x02) || || 0 0 1 0 1 || 5 || 05 || ㄷ (0x03) || ㅑ (0x02) || ㄴ (0x03) || || 0 0 1 1 0 || 6 || 06 || ㄸ (0x04) || ㅒ (0x03) || ㄵ (0x04) || || 0 0 1 1 1 || 7 || 07 || ㄹ (0x05) || ㅓ (0x04) || ㄶ (0x05) || || 0 1 0 0 0 || 8 || 08 || ㅁ (0x06) || 미정의 || ㄷ (0x06) || || 0 1 0 0 1 || 9 || 09 || ㅂ (0x07) || 미정의 || ㄹ (0x07) || || 0 1 0 1 0 || 10 || 0A || ㅃ (0x08) || ㅔ (0x05) || ㄺ (0x08) || || 0 1 0 1 1 || 11 || 0B || ㅅ (0x09) || ㅕ (0x06) || ㄻ (0x09) || || 0 1 1 0 0 || 12 || 0C || ㅆ (0x0a) || ㅖ (0x07) || ㄼ (0x0a) || || 0 1 1 0 1 || 13 || 0D || ㅇ (0x0b) || ㅗ (0x08) || ㄽ (0x0b) || || 0 1 1 1 0 || 14 || 0E || ㅈ (0x0c) || ㅘ (0x09) || ㄾ (0x0c) || || 0 1 1 1 1 || 15 || 0F || ㅉ (0x0d) || ㅙ (0x0a) || ㄿ (0x0d) || || 1 0 0 0 0 || 16 || 10 || ㅊ (0x0e) || 미정의 || ㅀ (0x0e) || || 1 0 0 0 1 || 17 || 11 || ㅋ (0x0f) || 미정의 || ㅁ (0x0f) || || 1 0 0 1 0 || 18 || 12 || ㅌ (0x10) || ㅚ (0x0b) || 미정의 || || 1 0 0 1 1 || 19 || 13 || ㅍ (0x11) || ㅛ (0x0c) || ㅂ (0x10) || || 1 0 1 0 0 || 20 || 14 || ㅎ (0x12) || ㅜ (0x0d) || ㅄ (0x11) || || 1 0 1 0 1 || 21 || 15 || 미정의 || ㅝ (0x0e) || ㅅ (0x12) || || 1 0 1 1 0 || 22 || 16 || 미정의 || ㅞ (0x0f) || ㅆ (0x13) || || 1 0 1 1 1 || 23 || 17 || 미정의 || ㅟ (0x10) || ㅇ (0x14) || || 1 1 0 0 0 || 24 || 18 || 미정의 || 미정의 || ㅈ (0x15) || || 1 1 0 0 1 || 25 || 19 || 미정의 || 미정의 || ㅊ (0x16) || || 1 1 0 1 0 || 26 || 1A || 미정의 || ㅠ (0x11) || ㅋ (0x17) || || 1 1 0 1 1 || 27 || 1B || 미정의 || ㅡ (0x12) || ㅌ (0x18) || || 1 1 1 0 0 || 28 || 1C || 미정의 || ㅢ (0x13) || ㅍ (0x19) || || 1 1 1 0 1 || 29 || 1D || 미정의 || ㅣ (0x14) || ㅎ (0x1a) || || 1 1 1 1 0 || 30 || 1E || 미정의 || 미정의 || 미정의 || || 1 1 1 1 1 || 31 || 1F || 미정의 || 미정의 || 미정의 || == 10x6x4 조합 방식 == * 초성은 10벌, 중성은 6벌, 종성은 4벌로 기본적인 벌수가 구성된 조합방식입니다. * 초성/중성/종성의 미려한 조합을 위해서는 최대 10x6x4 조합이 필요하다는 것이며 최소 8x4x4 조합만으로도 충분히 미려한 조합을 이뤄낼 수는 있습니다. * 초성 |10x6x4 조합 방식 초성| 종성여부 || 벌수 || 중성의 종류 || 초성 사용의 예 || || 종성채움 || 1 ||'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅣ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ' ||'가', '개', '갸', '걔', '기', ... || || 종성채움 || 2 ||'ㅗ', 'ㅛ', 'ㅡ' ||'고', '교', '그', ... || || 종성채움 || 3 ||'ㅜ', 'ㅠ' ||'구', '규', ... || || 종성채움 || 4 ||'ㅘ', 'ㅙ', 'ㅚ', 'ㅢ' ||'과', '괘', '괴', '긔', ... || || 종성채움 || 5 ||'ㅝ', 'ㅞ', 'ㅟ' ||'궈', '궤', '귀', ... || || 종성코드 || 6 ||'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅣ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ' ||'각', '객', '갹', '걕', '긱', ... || || 종성코드 || 7 ||'ㅗ', 'ㅛ', 'ㅡ' ||'곡', '굑', '극', ... || || 종성코드 || 8 ||'ㅜ', 'ㅠ' ||'국', '귝', ... || || 종성코드 || 9 ||'ㅘ', 'ㅙ', 'ㅚ', 'ㅢ' ||'곽', '괙', '괵', '긕', ... || || 종성코드 || 10 ||'ㅝ', 'ㅞ', 'ㅟ' ||'궉', '궥', '귁', ... || * 중성 |10x6x4 조합 방식 중성| 종성여부 || 벌수 || 초성의 종류 || 중성 사용의 예 || || 종성채움 || 1 ||초성이 'ㄱ', 'ㅋ'일 때 ||'가', '고', '크', '커', ... || || 종성채움 || 2 ||초성이 'ㅎ'일 때 ||'하', '혀', '효', ... || || 종성채움 || 3 ||1, 2벌이 아닌 경우의 나머지 ||'배', '마', '나', '다', ... || || 종성코드 || 4 ||초성이 'ㄱ', 'ㅋ'일 때 ||'각', '곡', '클', '컽', '켞', ... || || 종성코드 || 5 ||초성이 'ㅎ'일 때 ||'한', '형', '혼', ... || || 종성코드 || 6 ||4, 5벌이 아닌 경우의 나머지 ||'백', '막', '낙', '독', ... || * 종성 |10x6x4 조합 방식 종성| 벌수 || 중성의 종류 || 종성 사용의 예 || || 1 ||'ㅏ', 'ㅑ', 'ㅘ', 'ㅣ'의 중성이 있는 경우 ||'각', '얇', '인', ... || || 2 ||'ㅓ', 'ㅕ', 'ㅚ', 'ㅝ', 'ㅟ', 'ㅢ'의 중성이 있는 경우 ||'건', '격', '원', '윈', '벽', ... || || 3 ||'ㅐ', 'ㅒ', 'ㅔ', 'ㅖ', 'ㅙ', ㅞ'의 중성이 있는 경우 ||'객', '액', '왠', '췔', ... || || 4 ||'ㅗ', 'ㅛ', 'ㅜ', 'ㅠ', 'ㅡ'의 중성이 있는 경우 ||'곡', '욕', '음', '흠', ... || == 옛 조합형과 완성형(!KSX1001, 변경 전 !KSC5601)간의 코드변환 == * 구현예제 소스 : [attachment:bitmap.tar.gz] == Unicode 에서의 조합방식 == * Unicode에 대한 훌륭함을 보강해서 정리하고자 간단히 Unicode 조합방식에 대해서 ISO/IEC 10646:2003 문서를 참고하여 적어봅니다. * 한글 자모영역(Hangul Jamo: U+1100 ~ U+11FF, 첫가끝 한글, 'ᄀ'~)에 정의되며 초성(U+1100~), 중성(U+1161~), 종성(U+11AB~) 로 구성됩니다. * 자모를 초성 자음 / 중성 모음 / 종성 자음 으로 각각 나누어서 한글자씩 대응하여 정의되어 있음. * 한글 호환 자모영역은(Hangul Compatibility Jamo: U+3131 ~ U+318E, 'ㄱ'~)에 정의됩니다. * 이 영역은 통상 자음 또는 모음을 낱자로 사용할때 (예: 'ㄱ', 'ㄴ', 'ㅏ', 'ㅐ')사용됩니다. (즉, 낱자로 사용되는 경우 첫가끝 자모가 아닌 호환 자모영역이 사용됩니다.) * 한글 반각 자모영역은 (Halfwidth Jamo, Halfwidth Hangul variants: U+FFA1 ~ U+FFDC, 'ᄀ'~)에 정의됩니다. * 이미 조합되어 그 자체가 하나의 글자로 취급되는 코드는 한글 음절영역(Precomposed hangul syllable: U+AC00 ~ U+D7A3)에 정의됩니다. * 간단한 규칙에 의거하여 각각 초성, 중성, 종성으로 분리해낼수가 있습니다. 대략 다음과 같은 공식을 이용합니다. * 초성 index 갯수 19개, 중성 index 갯수 21개, 종성 index 갯수 28개 (종성 없음에 대한 코드를 포함) 를 순서대로 조합하여 정의됩니다. (총 글자수는 11,172 자 = 19 x 21 x 28) {{{ 이미조합된글자(U+AC00 ~ U+D7A3) = 0xAC00 + ((초성 * (21 * 28)) + (중성 * 28) + 종성); }}} * UTF-8 sequence Encode/Decode 규약 ([^https://tools.ietf.org/html/rfc3629 RFC-3629]) * {{{#!plain Char. number range | UTF-8 octet sequence (hexadecimal) | (binary) --------------------+--------------------------------------------- 0000 0000-0000 007F | 0xxxxxxx <= 일반 ASCII는 1-bytes encoding 대역 (상위 MSB bit 가 0인 경우) 0000 0080-0000 07FF | 110xxxxx 10xxxxxx <= UTF-8 enconding 문자하나는 항상 상위 MSB가 적어도 2개 bit 가 1로 시작합니다. 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx }}} * 예제소스: [[attachment:utf-8-source-20181116.tar.gz]] * 조합형 Unicode값 과 실제 사용하게 되는 index 값은 다음과 같습니다. (none이 뜻하는것은 없는것으로 간주한다는 의미로 사용됩니다.) |조합형 Unicode index||||||| 첫가끝 코드 |||||| Precomposed hangul syllable 에 사용되는 index || || 값 || 초성 || 중성 || 종성 || 초성 || 중성 || 종성 || || 0 || ᄀ || ᅡ || none || ᄀ || ᅡ || none || || 1 || ᄁ || ᅢ || ᆨ || ᄁ || ᅢ || ᆨ || || 2 || ᄂ || ᅣ || ᆩ || ᄂ || ᅣ || ᆩ || || 3 || ᄃ || ᅤ || ᆪ || ᄃ || ᅤ || ᆪ || || 4 || ᄄ || ᅥ || ᆫ || ᄄ || ᅥ || ᆫ || || 5 || ᄅ || ᅦ || ᆬ || ᄅ || ᅦ || ᆬ || || 6 || ᄆ || ᅧ || ᆭ || ᄆ || ᅧ || ᆭ || || 7 || ᄇ || ᅨ || ᆮ || ᄇ || ᅨ || ᆮ || || 8 || ᄈ || ᅩ || ᆯ || ᄈ || ᅩ || ᆯ || || 9 || ᄉ || ᅪ || ᆰ || ᄉ || ᅪ || ᆰ || || 10 || ᄊ || ᅫ || ᆱ || ᄊ || ᅫ || ᆱ || || 11 || ᄋ || ᅬ || ᆲ || ᄋ || ᅬ || ᆲ || || 12 || ᄌ || ᅭ || ᆳ || ᄌ || ᅭ || ᆳ || || 13 || ᄍ || ᅮ || ᆴ || ᄍ || ᅮ || ᆴ || || 14 || ᄎ || ᅯ || ᆵ || ᄎ || ᅯ || ᆵ || || 15 || ᄏ || ᅰ || ᆶ || ᄏ || ᅰ || ᆶ || || 16 || ᄐ || ᅱ || ᆷ || ᄐ || ᅱ || ᆷ || || 17 || ᄑ || ᅲ || ᆸ || ᄑ || ᅲ || ᆸ || || 18 || ᄒ || ᅳ || ᆹ || ᄒ || ᅳ || ᆹ || || 19 || ᄓ || ᅴ || ᆺ || || ᅴ || ᆺ || || 20 || ᄔ || ᅵ || ᆻ || || ᅵ || ᆻ || || 21 || ᄕ || ᅶ || ᆼ || || || ᆼ || || 22 || ᄖ || ᅷ || ᆽ || || || ᆽ || || 23 || ᄗ || ᅸ || ᆾ || || || ᆾ || || 24 || ᄘ || ᅹ || ᆿ || || || ᆿ || || 25 || ᄙ || ᅺ || ᇀ || || || ᇀ || || 26 || ᄚ || ᅻ || ᇁ || || || ᇁ || || 27 || ᄛ || ᅼ || ᇂ || || || ᇂ || || 28 || ᄜ || ᅽ || ᇃ || || || ᇃ || || 29 || ᄝ || ᅾ || ᇄ || || || || || 30 || ᄞ || ᅿ || ᇅ || || || || || 31 || ᄟ || ᆀ || ᇆ || || || || || 32 || ᄠ || ᆁ || ᇇ || || || || || 33 || ᄡ || ᆂ || ᇈ || || || || || 34 || ᄢ || ᆃ || ᇉ || || || || || 35 || ᄣ || ᆄ || ᇊ || || || || || 36 || ᄤ || ᆅ || ᇋ || || || || || 37 || ᄥ || ᆆ || ᇌ || || || || || 38 || ᄦ || ᆇ || ᇍ || || || || || 39 || ᄧ || ᆈ || ᇎ || || || || || 40 || ᄨ || ᆉ || ᇏ || || || || || 41 || ᄩ || ᆊ || ᇐ || || || || || 42 || ᄪ || ᆋ || ᇑ || || || || || 43 || ᄫ || ᆌ || ᇒ || || || || || 44 || ᄬ || ᆍ || ᇓ || || || || || 45 || ᄭ || ᆎ || ᇔ || || || || || 46 || ᄮ || ᆏ || ᇕ || || || || || 47 || ᄯ || ᆐ || ᇖ || || || || || 48 || ᄰ || ᆑ || ᇗ || || || || || 49 || ᄱ || ᆒ || ᇘ || || || || || 50 || ᄲ || || ᇙ || || || || || 51 || ᄳ || || ᇚ || || || || || 52 || ᄴ || || ᇛ || || || || || 53 || ᄵ || || ᇜ || || || || || 54 || ᄶ || || ᇝ || || || || || 55 || ᄷ || || ᇞ || || || || || 56 || ᄸ || || ᇟ || || || || || 57 || ᄹ || || ᇠ || || || || || 58 || ᄺ || || ᇡ || || || || || 59 || ᄻ || || ᇢ || || || || || 60 || ᄼ || || ᇣ || || || || || 61 || ᄽ || || ᇤ || || || || || 62 || ᄾ || || ᇥ || || || || || 63 || ᄿ || || ᇦ || || || || || 64 || ᅀ || || ᇧ || || || || || 65 || ᅁ || || ᇨ || || || || || 66 || ᅂ || || ᇩ || || || || || 67 || ᅃ || || ᇪ || || || || || 68 || ᅄ || || ᇫ || || || || || 69 || ᅅ || || ᇬ || || || || || 70 || ᅆ || || ᇭ || || || || || 71 || ᅇ || || ᇮ || || || || || 72 || ᅈ || || ᇯ || || || || || 73 || ᅉ || || ᇰ || || || || || 74 || ᅊ || || ᇱ || || || || || 75 || ᅋ || || ᇲ || || || || || 76 || ᅌ || || ᇳ || || || || || 77 || ᅍ || || ᇴ || || || || || 78 || ᅎ || || ᇵ || || || || || 79 || ᅏ || || ᇶ || || || || || 80 || ᅐ || || ᇷ || || || || || 81 || ᅑ || || ᇸ || || || || || 82 || ᅒ || || ᇹ || || || || || 83 || ᅓ || || || || || || || 84 || ᅔ || || || || || || || 85 || ᅕ || || || || || || || 86 || ᅖ || || || || || || || 87 || ᅗ || || || || || || || 88 || ᅘ || || || || || || || 89 || ᅙ || || || || || || == 참고사항 == * [wiki:AsciiTable ASCII 표] * Javascript 에서 UTF-8 문자열 입력으로부터 실제 문자개수 (len) 가 아닌 octets (bytes 길이) 를 반환하는 함수 구현예제 (즉, '한글' 인 경우 문자개수는 2개의 문자 이지만 octets 는 6 bytes로 반환됨) {{{#!enscript javascript function utf_string_octets(str){ // 1. 값이 없을 경우 0 return var size = 0; if(!str) { return size; } try{ /* 2. 성능면에서 우수한 bytes 계산 로직 실행 -. jhcho: 제일 간결하고 정확한 bytes계산이 이루어지며 속도면에서도 유리할 것으로 보이나 Mobile browser 호환성이 떨어짐. -. https://www.javascripture.com/Blob, https://developer.mozilla.org/ko/docs/Web/API/Blob */ return new Blob([str]).size; }catch(e){ try{ /* 3. 호환성면에서 우수한 bytes 계산 로직 실행(2번에서 실패 하였을 경우 실행 ex-모바일) -. UTF-8 웹 상에서는 정상동작하지만 EUC-KR 환경에는 동작 보장되지 않음. -. Browser 호환성 제일 높은 방법 -: 최저 버젼(IE6, IE7, FF 2.0, Safari 3, Opera 9.2) ~ 최신 버젼 */ for(var i = 0;i < str.length;i++) { var unicode = str.charCodeAt(i); if(unicode <= 0x7f) { // U+0000 ~ U+007F size += 1; }else if(unicode <= 0x7ff) { // U+0080 ~ U+07FF size += 2; }else if(unicode <= 0xffff) { // U+0800 ~ U+FFFF size += 3; }else { // U+10000 ~ U+10FFFF size += 4; } } return size; }catch(e){ return 0; // 예외 } } } }}}