Skip to content

한글 조합 원리

초성·중성·종성, 유니코드 조합형/완성형/호환 자모, 완성형 공식, NFD/NFC

한글은 초성(첫소리)·중성(가운뎃소리)·종성(끝소리) 세 부분으로 한 음절을 이룬다. 초성은 자음, 중성은 모음, 종성은 받침(자음 또는 없음)이다. 유니코드에서는 이 조합을 완성형(Hangul Syllables) 한 글자로 쓰거나, 조합형(Hangul Jamo) 자모 시퀀스로 쓴다.


flowchart LR
    subgraph 음절["한글 음절"]
        direction TB
        L["초성 (L)"]
        V["중성 (V)"]
        T["종성 (T)"]
    end
    
    L --> |필수| V
    V --> |선택| T
    
    subgraph 예시["예: 한"]
        direction TB
        L2["ㅎ (L=18)"]
        V2["ㅏ (V=0)"]
        T2["ㄴ (T=4)"]
    end

음절 조합 공식:

코드 포인트 = 0xAC00 + (L × 588) + (V × 28) + T
음절LVT계산결과
0000xAC00 + 0U+AC00
2000xAC00 + 1176U+B098
18040xAC00 + 10584 + 4U+D55C
01880xAC00 + 504 + 8U+AE00

  • 자모: 한글의 낱글자. 초성(자음), 중성(모음), 종성(받침)으로 나뉜다.
  • 음절: 초성 + 중성, 또는 초성 + 중성 + 종성이 합쳐진 한 글자. 예: 가, 각, 갈.
  • 조합 규칙: 반드시 초성 + 중성이 먼저 오고, 그다음 종성이 선택이다. 따라서 “초성만”, “중성만”, “종성만” 단독으로는 한 음절이 되지 않는다.

유니코드 명세(Unicode FAQ - Korean)에 따르면, 한글 음절은 <LV> (초성+중성) 또는 <LVT> (초성+중성+종성) 시퀀스로 표현된다.

1.2 현대 한글에서 쓰는 자모 개수

Section titled “1.2 현대 한글에서 쓰는 자모 개수”

완성형 한글 음절(U+AC00~U+D7A3)을 만드는 데 쓰는 자모는 다음 부분집합이다(Unicode FAQ - Korean 인용).

  • 초성(L, Leading consonant): 19개 (U+1100~U+1112)
  • 중성(V, Vowel): 21개 (U+1161~U+1175)
  • 종성(T, Trailing consonant): 27개 (U+11A8~U+11C2) + 받침 없음 1가지 → 총 28가지

이 19×21×28 조합 중 11,172개만 유니코드 완성형 블록에 직접 부여되어 있다.

  • 399개 = <LV> (19 × 21): 받침 없는 글자. 예: 가, 나, 다.
  • 10,773개 = <LVT> (19 × 21 × 27): 받침 있는 글자. 예: 각, 갈, 감.

현대 한글 완성형에 쓰이는 초성은 U+1100~U+1112 한 블록에 연속 배치되어 있다. 인덱스 0~18과 1:1 대응한다.

인덱스코드 포인트자모이름(유니코드)
0U+1100Hangul Choseong Kiyeok
1U+1101Hangul Choseong Ssangkiyeok
2U+1102Hangul Choseong Nieun
3U+1103Hangul Choseong Tikeut
4U+1104Hangul Choseong Ssangtikeut
5U+1105Hangul Choseong Rieul
6U+1106Hangul Choseong Mieum
7U+1107Hangul Choseong Pieup
8U+1108Hangul Choseong Ssangpieup
9U+1109Hangul Choseong Sios
10U+110AHangul Choseong Ssangsios
11U+110BHangul Choseong Ieung
12U+110CHangul Choseong Cieuc
13U+110DHangul Choseong Ssangcieuc
14U+110EHangul Choseong Chieuch
15U+110FHangul Choseong Khieukh
16U+1110Hangul Choseong Thieuth
17U+1111Hangul Choseong Phieuph
18U+1112Hangul Choseong Hieuh

U+1113 이후는 옛초성(Old initial consonants) 이며, 완성형 11,172자 계산에는 쓰이지 않는다.


현대 한글 완성형에 쓰이는 중성은 U+1161~U+1175에 연속 배치되어 있다. 인덱스 0~20과 1:1 대응한다.

인덱스코드 포인트자모이름(유니코드)
0U+1161Hangul Jungseong A
1U+1162Hangul Jungseong Ae
2U+1163Hangul Jungseong Ya
3U+1164Hangul Jungseong Yae
4U+1165Hangul Jungseong Eo
5U+1166Hangul Jungseong E
6U+1167Hangul Jungseong Yeo
7U+1168Hangul Jungseong Ye
8U+1169Hangul Jungseong O
9U+116AHangul Jungseong Wa
10U+116BHangul Jungseong Wae
11U+116CHangul Jungseong Oe
12U+116DHangul Jungseong Yo
13U+116EHangul Jungseong U
14U+116FHangul Jungseong Weo
15U+1170Hangul Jungseong We
16U+1171Hangul Jungseong Wi
17U+1172Hangul Jungseong Yu
18U+1173Hangul Jungseong Eu
19U+1174Hangul Jungseong Yi
20U+1175Hangul Jungseong I

U+1160은 Hangul Jungseong Filler(Vf) 로, “중성만 단독”일 때 <Lf, V> 형태로 쓸 때 사용한다. U+1176 이후는 옛중성이다.


4. 종성(Jongseong, T) — 28가지 (27개 자모 + 없음)

Section titled “4. 종성(Jongseong, T) — 28가지 (27개 자모 + 없음)”

종성은 받침이 있는 경우 27개 자모(U+11A8U+11C2), 받침이 없는 경우 1가지(인덱스 0)로 총 28가지다. 완성형 공식에서는 종성 인덱스를 027로 두고, 0을 “받침 없음”으로 둔다.

인덱스코드 포인트자모이름(유니코드)
0(없음)받침 없음
1U+11A8Hangul Jongseong Kiyeok
2U+11A9Hangul Jongseong Ssangkiyeok
3U+11AAHangul Jongseong Kiyeok-Sios
4U+11ABHangul Jongseong Nieun
5U+11ACHangul Jongseong Nieun-Cieuc
6U+11ADHangul Jongseong Nieun-Hieuh
7U+11AEHangul Jongseong Tikeut
8U+11AFHangul Jongseong Rieul
9U+11B0Hangul Jongseong Rieul-Kiyeok
10U+11B1Hangul Jongseong Rieul-Mieum
11U+11B2Hangul Jongseong Rieul-Pieup
12U+11B3Hangul Jongseong Rieul-Sios
13U+11B4Hangul Jongseong Rieul-Thieuth
14U+11B5Hangul Jongseong Rieul-Phieuph
15U+11B6Hangul Jongseong Rieul-Hieuh
16U+11B7Hangul Jongseong Mieum
17U+11B8Hangul Jongseong Pieup
18U+11B9Hangul Jongseong Pieup-Sios
19U+11BAHangul Jongseong Sios
20U+11BBHangul Jongseong Ssangsios
21U+11BCHangul Jongseong Ieung
22U+11BDHangul Jongseong Cieuc
23U+11BEHangul Jongseong Chieuch
24U+11BFHangul Jongseong Khieukh
25U+11C0Hangul Jongseong Thieuth
26U+11C1Hangul Jongseong Phieuph
27U+11C2Hangul Jongseong Hieuh

U+11C3 이후는 옛종성이다. 초성·중성과 달리 **종성 “없음”**이 한 가지 상태이기 때문에, 완성형 인덱스 공식에서 T는 0~27까지 28가지로 둔다.


한글 한 음절은 초성 → 중성 → (종성) 순서로만 쌓인다.

stateDiagram-v2
    [*] --> L: 자음 입력
    
    L --> L: 쌍자음
    L --> LV: 모음 입력
    
    LV --> LV: 겹모음
    LV --> LVT: 종성 추가
    LV --> COMMIT_NEW_LV: commit
    
    LVT --> LVT: 겹받침
    LVT --> COMMIT_NEW_L: commit
    LVT --> SPLIT_COMMIT: 종성 분리
    
    COMMIT_NEW_LV --> LV
    COMMIT_NEW_L --> L
    SPLIT_COMMIT --> LV

상태별 preedit 예시:

  • L: “ㄱ” (초성만)
  • LV: “가” (초성+중성)
  • LVT: “각” (초성+중성+종성)
  • SPLIT_COMMIT: “각” + ㅏ → commit “가” + preedit “가”
현재 상태입력동작다음 상태preedit 변화
없음자음L 설정L"" → “ㄱ”
L같은 자음쌍자음L”ㄱ” → “ㄲ”
L다른 자음L 교체L”ㄱ” → “ㄴ”
L모음V 설정LV”ㄱ” → “가”
LV겹모음 가능 모음V 갱신LV”고” → “과”
LV겹모음 불가 모음commit, 새 LVLV”가” → commit “가”, “아”
LV종성 가능 자음T 설정LVT”가” → “각”
LV종성 불가 자음commit, 새 LL”가” → commit “가”, “ㄸ”
LVT겹받침 가능 자음T 갱신LVT”갈” → “갈ㅁ”(삶)
LVT겹받침 불가 자음commit, 새 LL”각” → commit “각”, “ㄴ”
LVT모음분리, commit, 새 LVLV”각” → commit “가”, “가”
  • 초성만: L만 있음. preedit에는 “ㄱ”처럼 자모만 보이거나 (L, Vf)로 표시.
  • 초성+중성: (L, V). 완성형 한 글자 계산 가능. preedit에 “가” 표시.
  • 초성+중성+종성: (L, V, T). preedit에 “각” 표시. 다음 자모 입력 시 commit 후 새 상태로 전이.

유니코드에서 한글 자모는 conjoining(연결) 방식이다. 즉, L·V·T는 “기준 문자 + 결합 부호”가 아니라, L–V–T 순서로 나열하면 한 음절로 해석된다.

  • 유효한 음절: <L, V> 또는 <L, V, T>.
  • L만 있음: L 뒤에 V가 오지 않으면 “불완전한 음절”. 표시할 때는 <L, Vf> (Vf = U+1160 Hangul Jungseong Filler)로 간주해 렌더링한다(Unicode FAQ).
  • V만 있음: V 앞에 L이 없으면 <Lf, V> (Lf = U+115F Hangul Choseong Filler)로 간주한다.
  • T만 있음: T 앞에 <L,V>가 없으면 <Lf, Vf, T> 로 간주한다.

IME는 사용자가 “ㄱ”만 입력한 상태를 “조합 중”으로 두고, “ㅏ”를 넣으면 “가”로 합친다. 이때 내부적으로는 (L=0, V=0, T=0) → U+AC00으로 변환하는 식으로 동작한다.

겹모음(ㅘ, ㅙ, …), 겹받침(ㄳ, ㄵ, …), 종성→다음 초성 변환 규칙·테이블은 한글 조합 규칙(겹모음·겹받침)를 참고한다. 2벌식·3벌식 키 매핑·상태 전이 차이는 2벌식 알고리즘, 3벌식 알고리즘을 참고한다.


블록범위개수용도
Hangul Syllables (완성형)U+AC00~U+D7A311,172L,V,T 인덱스로 계산 가능한 한 음절 한 글자.
Hangul Jamo (조합형 자모)U+1100~U+11FF초성·중성·종성·옛자모·FillerL, V, T 시퀀스로 음절 표현. NFD 시 사용.
Hangul Compatibility Jamo (호환 자모)U+3131~U+318E호환용레거시 코드페이지 호환. 조합형과 1:1 대응 아님.
  • 완성형: IME가 commit할 때 보통 이 블록의 문자를 쓴다. 한 코드 포인트 = 한 음절.
  • 조합형: 정규화(NFD), 검색, 옛한글 등에서 L·V·T 시퀀스로 쓴다.
  • 호환 자모: KS X 1001 등 레거시 매핑용. 새로 만드는 시스템에서는 완성형 또는 조합형 자모(U+1100~)를 쓰는 것이 좋다.

유니코드 명세(Unicode FAQ - Korean, [KL])에 따른 완성형 코드 포인트 계산:

S = 0xAC00 + (L × 588) + (V × 28) + T
  • L: 초성 인덱스 (0~18)
  • V: 중성 인덱스 (0~20)
  • T: 종성 인덱스 (0~27, 0 = 받침 없음)
  • 28 = 종성 경우의 수. 27개 자모 + “받침 없음” 1 = 28.
  • 588 = 한 (L, V) 조합당 가질 수 있는 음절 수. 즉 21(중성) × 28(종성) = 588.

따라서:

  • (L, V) 한 쌍이 고정되면, T만 0~27로 바꿔 28개 음절이 나온다. 예: 가(0,0,0), 각(0,0,1), 갂(0,0,2), …
  • L이 018, V가 020이므로 19 × 21 = 399 개의 (L,V) 쌍이 있고, 각각 28개 음절 → 399×28 = 11,172. 그중 T=0인 399개가 LV 음절, T≥1인 399×27 = 10,773개가 LVT 음절이다.
  • : L=0, V=0, T=0 → S = 0xAC00 + 0 = U+AC00.
  • : L=0, V=0, T=1 → S = 0xAC00 + 28 = U+AC1C.
  • : L=0, V=0, T=27 → S = 0xAC00 + (27×1) = 0xAC1B. (실제 글자는 “갛” U+AC1B.)

7.4 역계산 (코드 포인트 → L, V, T)

Section titled “7.4 역계산 (코드 포인트 → L, V, T)”

S = 0xAC00 + (L×588) + (V×28) + T 이므로, S − 0xAC00을 28로 나누면 몫과 나머지로 V, T를 복원하고, 다시 몫을 21로 나누면 L, V를 복원할 수 있다.

diff = (S - 0xAC00)
T = diff % 28
diff = diff // 28
V = diff % 21
L = diff // 21

  • U+115F Hangul Choseong Filler (Lf): “초성 없음”을 나타내는 자리 채우기.
  • U+1160 Hangul Jungseong Filler (Vf): “중성 없음”을 나타내는 자리 채우기.

Unicode FAQ에 따르면:

  • L만 있을 때: 표시는 <L, Vf> 로 한다.
  • V만 있을 때: 표시는 <Lf, V> 로 한다.
  • T만 있을 때: 표시는 <Lf, Vf, T> 로 한다.

IME에서 “ㄱ”만 입력한 상태는 아직 음절이 완성되지 않은 “조합 중”이며, 화면에는 보통 “ㄱ”처럼 보이게 하거나, (L,Vf) 시퀀스로 렌더링할 수 있다.


  • NFC(Normalization Form Composed): 가능한 <L,V>, <L,V,T> 시퀀스를 한 코드 포인트 완성형(U+AC00~U+D7A3)으로 합친다.
  • NFD(Normalization Form Decomposed): 완성형 한 글자를 L, V, T 조합형 자모(U+1100~) 시퀀스로 풀어 쓴다.

같은 “가”도 NFC면 U+AC00 한 코드 포인트, NFD면 U+1100, U+1161 두 코드 포인트가 된다. 문자열 비교·검색·저장 시 NFC/NFD 중 하나로 통일해 두는 것이 좋다.


IME는 사용자 키 입력을 “자모 시퀀스”로 해석하고, (L, V, T) 상태를 유지한다. 그 상태가 유효한 (L,V) 또는 (L,V,T) 일 때마다 위 공식으로 완성형 코드 포인트를 계산해, 조합 중 문자열(preedit) 으로 앱에 넘긴다. 사용자가 스페이스·엔터를 누르거나 다음 자모를 넣어 “이 음절 확정”이 되면, 그때 commit으로 문서에 반영한다.

플랫폼·입력기마다 “조합 중에 완성형을 쓸지, 조합형 자모 시퀀스를 쓸지”가 다를 수 있으나, 웹에서는 대부분 완성형 한 글자(또는 여러 글자)로 CompositionEvent.data에 전달된다.