🇺🇳

Han Unification: How Unicode Merged 100,000 CJK CharactersHan Unification: Unicodeが10万字の漢字を統合した方法

How the IRG decided which characters from Japan, China, Taiwan, and Korea are 'the same,' with a tool to check any character's source.日中台韓の漢字がどのように統合されたか。IRGソースフラグで各文字の出自を確認。

The Problem: Same Origin, Different Shapes

Chinese characters (漢字/汉字) are used across four major writing systems: Chinese (simplified and traditional), Japanese, Korean, and Vietnamese (historically). Over centuries, the same character evolved different shapes in each region.

Consider the character meaning “bone”: in Japan it is written as 骨 with a slightly different stroke structure than the Chinese form. Should Unicode assign them the same code point or different ones?

The Unicode Consortium chose Han Unification: characters that share the same origin and meaning are assigned a single code point, even if their glyphs differ across regions. The font and language tag determine which visual form is rendered.

ConceptExampleCode point
Unified繋 (JP) vs 繋 (CN)Same: U+7E4B
Not unified渡 vs 度Different: U+6E21 vs U+5EA6

The Source Separation Rule

The core principle governing Han Unification is the Source Separation Rule: if two characters were encoded as separate code points in any of the source standards (national character sets from China, Japan, Korea, Taiwan, etc.), they must remain separate in Unicode.

Conversely, if a character appears in multiple source standards at what the IRG (Ideographic Rapporteur Group) judges to be the “same position,” it is unified into one code point.

Each unified character carries source references (also called IRG source flags) that record which national standards include it:

Source prefixStandardCountry/Region
GGB 2312 / GB 18030 / etc.China (PRC)
JJIS X 0208 / JIS X 0213Japan
KKS X 1001 / KS X 1002Korea
TCNS 11643Taiwan
VTCVNVietnam
HHKSCSHong Kong

This tool shows the IRG source flags for every CJK character, letting you trace exactly which standards contributed each code point.

Reading IRG Source Flags

When you inspect a CJK character in this tool, you may see source data like G0-3A3A J0-3441 T1-4E5B K0-7956. Here is how to decode these:

FlagMeaning
G0-3A3AGB 2312 row 26, col 26 (China source)
J0-3441JIS X 0208 row 20, col 33 (Japan source)
T1-4E5BCNS 11643 plane 1, row 46, col 59 (Taiwan source)
K0-7956KS X 1001 row 89, col 70 (Korea source)

The number after the letter indicates which level of the standard: G0 = GB 2312 (level 0), G1 = GB 12345, J0 = JIS X 0208, J1 = JIS X 0212, and so on.

A character with sources from all four major regions (G, J, K, T) is strongly unified — all four national standards agreed this was one character. A character with only one source (e.g., only J) may be Japan-specific.

CJK Extensions A through I

The original CJK Unified Ideographs block (U+4E00–U+9FFF) holds 20,992 characters from the most common national standards. But this was not nearly enough. Unicode has added extensions over the decades:

BlockRangeCountYearNote
CJK UnifiedU+4E00–9FFF20,9921993Core set (GB, JIS, KS, CNS)
Extension AU+3400–4DBF6,5921999Rare characters from CNS, JIS X 0213
Extension BU+20000–2A6DF42,7202001Historic, variant, rare
Extension CU+2A700–2B73F4,1542009Additional rare characters
Extension DU+2B740–2B81F2222010Urgent additions
Extension EU+2B820–2CEAF5,7622015Continued expansion
Extension FU+2CEB0–2EBEF7,4732017Further additions
Extension GU+30000–3134F4,9392020Includes oracle bone script
Extension HU+31350–323AF4,1922022Continued expansion
Extension IU+2EBF0–2F7FF6222023CJK ideographs for personal names

Extensions B and beyond live in the Supplementary Ideographic Plane (SIP), requiring surrogate pairs in UTF-16. This means "𠀀".length in JavaScript returns 2, not 1.

The Controversy

Han Unification remains one of Unicode's most debated decisions. Critics argue:

  • Loss of distinction: Japanese and Chinese readers may expect different stroke forms for the same code point. Relying on lang attributes and fonts is fragile.
  • Font dependency: Without correct language tagging, a CJK character may render in the “wrong” regional form, confusing readers.
  • Philosophical objection: Some scholars argue that regional variants have diverged enough to be distinct characters, not merely glyph variants.

Defenders counter:

  • Precedent: Latin ‘a’ renders differently across fonts (serif vs sans-serif) without getting separate code points. Regional CJK glyph variation is analogous.
  • Practicality: Without unification, CJK blocks would be 3–4x larger, making interoperability harder.
  • IVS escape valve: Ideographic Variation Sequences allow specifying exact glyph forms when needed.

CJK Compatibility Ideographs: The Exceptions

Despite the unification philosophy, Unicode does include some duplicated CJK characters in the CJK Compatibility Ideographs block (U+F900–U+FAFF). These exist for round-trip compatibility with source standards that encoded the same character twice.

For example, U+F91D (隷) is a CJK Compatibility Ideograph that duplicates U+96B7 (隷). Under NFC normalization, the compatibility ideograph maps to the unified form:

// CJK Compatibility Ideograph → Unified form
"\uF91D".normalize("NFC")
// → "隷" (U+96B7)

// Check if a character is in the compatibility block:
const cp = "隷".codePointAt(0); // U+F91D
const isCompat = cp >= 0xF900 && cp <= 0xFAFF;

There are 472 CJK Compatibility Ideographs. Most exist because the Korean KS X 1001 standard encoded some variant forms separately, and the Source Separation Rule required preserving them.

問題: 同じ起源、異なる字形

漢字は4つの主要な文字体系で使用されています: 中国語(簡体字・繁体字)、日本語、韓国語、そしてベトナム語(歴史的)。数世紀を経て、同じ文字が各地域で異なる字形に発展しました。

例えば「骨」という文字: 日本では中国語の字形とわずかに異なる画構造で書かれます。Unicode は同じコードポイントを割り当てるべきでしょうか、それとも別々にすべきでしょうか?

Unicode コンソーシアムは Han Unification(漢字統合)を選択しました: 同じ起源と意味を共有する文字は、地域間でグリフが異なっていても単一のコードポイントに割り当てられます。どの視覚形式でレンダリングされるかはフォントと言語タグによって決まります。

概念コードポイント
統合された繋(JP)vs 繋(CN)同一: U+7E4B
統合されない渡 vs 度別々: U+6E21 vs U+5EA6

ソース分離規則

漢字統合を統治する中核原則がソース分離規則(Source Separation Rule)です: 2つの文字がいずれかのソース規格(中国、日本、韓国、台湾等の国家文字集合)で別々のコードポイントとしてエンコードされていた場合、Unicode でも別々のままでなければなりません。

逆に、IRG(Ideographic Rapporteur Group、表意文字小委員会)が「同じ位置」と判断した文字が複数のソース規格に現れる場合、1つのコードポイントに統合されます。

統合された各文字にはソース参照(IRG ソースフラグ)が付与され、どの国家規格がそれを含むか記録されています:

ソース接頭辞規格国/地域
GGB 2312 / GB 18030 等中国(大陸)
JJIS X 0208 / JIS X 0213日本
KKS X 1001 / KS X 1002韓国
TCNS 11643台湾
VTCVNベトナム
HHKSCS香港

このツールはすべての CJK 文字の IRG ソースフラグを表示し、各コードポイントにどの規格が寄与したかを追跡できます。

IRG ソースフラグの読み方

このツールで CJK 文字を検査すると、G0-3A3A J0-3441 T1-4E5B K0-7956 のようなソースデータが表示されることがあります。読み方は以下の通りです:

フラグ意味
G0-3A3AGB 2312 26区26点(中国ソース)
J0-3441JIS X 0208 20区33点(日本ソース)
T1-4E5BCNS 11643 第1面 46区59点(台湾ソース)
K0-7956KS X 1001 89区70点(韓国ソース)

文字の後の数字は規格のレベルを示します: G0 = GB 2312(レベル0)、G1 = GB 12345、J0 = JIS X 0208、J1 = JIS X 0212 など。

4つの主要地域すべて(G, J, K, T)のソースを持つ文字は強く統合されています — 4つの国家規格がこれを1つの文字と認めたことを意味します。1つのソースのみ(例: J のみ)の文字は日本固有の可能性があります。

CJK 拡張 A から I まで

元の CJK 統合漢字ブロック(U+4E00–U+9FFF)は最も一般的な国家規格から 20,992 文字を収録しています。しかしこれでは全く足りませんでした。Unicode は数十年にわたり拡張を追加してきました:

ブロック範囲文字数備考
CJK 統合漢字U+4E00–9FFF20,9921993基本集合(GB, JIS, KS, CNS)
拡張AU+3400–4DBF6,5921999CNS, JIS X 0213 の稀少文字
拡張BU+20000–2A6DF42,7202001歴史的・異体・稀少文字
拡張CU+2A700–2B73F4,1542009追加の稀少文字
拡張DU+2B740–2B81F2222010緊急追加
拡張EU+2B820–2CEAF5,7622015継続的拡張
拡張FU+2CEB0–2EBEF7,4732017さらなる追加
拡張GU+30000–3134F4,9392020甲骨文字を含む
拡張HU+31350–323AF4,1922022継続的拡張
拡張IU+2EBF0–2F7FF6222023人名用漢字

拡張B 以降は補助表意文字面(SIP)に配置され、UTF-16 ではサロゲートペアが必要です。つまり JavaScript では "𠀀".length は 1 ではなく 2 を返します。

論争

漢字統合は Unicode で最も議論の多い決定の一つであり続けています。批判側の主張:

  • 区別の喪失: 日本語と中国語の読者は同じコードポイントに対して異なる画形を期待する場合がある。lang 属性とフォントに頼るのは脆弱。
  • フォント依存: 正しい言語タグがなければ、CJK 文字が「間違った」地域形式でレンダリングされ、読者を混乱させる。
  • 哲学的異議: 地域変種は十分に分岐しており、単なるグリフ変種ではなく別個の文字であると主張する学者もいる。

擁護側の反論:

  • 先例: ラテン文字の ‘a’ もフォントによって異なる形で描画される(セリフ vs サンセリフ)が、別のコードポイントは与えられない。地域的な CJK グリフ変種も同様。
  • 実用性: 統合なしでは CJK ブロックは3〜4倍の大きさになり、相互運用性が困難に。
  • IVS という安全弁: 異体字シーケンス(IVS)により、必要時に正確なグリフ形式を指定可能。

CJK 互換漢字: 例外

統合の哲学にもかかわらず、Unicode には CJK 互換漢字ブロック(U+F900–U+FAFF)に重複した CJK 文字が含まれています。これらは同じ文字を2度エンコードしたソース規格との往復互換性のために存在します。

例えば U+F91D(隷)は U+96B7(隷)を複製する CJK 互換漢字です。NFC 正規化では互換漢字は統合形式にマッピングされます:

// CJK 互換漢字 → 統合形式
"\uF91D".normalize("NFC")
// → "隷" (U+96B7)

// 文字が互換ブロックにあるか確認:
const cp = "隷".codePointAt(0); // U+F91D
const isCompat = cp >= 0xF900 && cp <= 0xFAFF;

CJK 互換漢字は 472 文字あります。大半は韓国の KS X 1001 規格がいくつかの変種形式を個別にエンコードしていたため、ソース分離規則に従って保持されたものです。