银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
  268 随笔 :: 2 文章 :: 2605 评论 :: 48 引用

公告

引言

中日韩越統一表意文字(CJKV Unified Ideographs),也称統一汉字(Unihan),目的是要把分別来自中文、日文、韩文、越文、壮文中,对於相同起源、本义相同、形状一样或稍异的表意文字,应赋予其在 ISO 10646 及統一码(Unicode)标准中有相同编码。

截至目前 (2012年,Unicode 6.2) 为止,中日韩越统一表意文字共有 75,617 字,来源于以下几个方面:

  • 统一汉字基本集,共 20,941 字,其范围为:U+4E00 - U+9FCC。
  • 上面的统一汉字基本集中 U+4E00 - U+9FA5 的 20,902 个汉字(GB13000:GBK),是在1993年引进的(Unicode 1.0)。
  • 上面的 GBK 汉字包括 GB2312 的 6,763 个汉字。
  • 上面的统一汉字基本集中的 U+9FA6 - U+9FBB 范围的 22 个汉字是在2005年引进的(Unicode 4.1)。
  • 上面的统一汉字基本集中的 U+9FBC - U+9FC3 范围的 8 个汉字是在2008年4月引进的(Unicode 5.1)。
  • 上面的统一汉字基本集中的 U+9FCC 这一个汉字是在2012年引进的(Unicode 6.1)。
  • 扩展区(A),共 6,582 字,其范围为:U+3400 - U+4DB5。这是在1999年引进的。
  • 扩展区(B),共 42,711 字,其范围为:U+20000 - U+2A6D6。这是在2001年引进的。
  • 扩展区(C),共 4,149 字,其范围为:U+2A700 - U+2B734。这是在2009年10月引进的(Unicode 5.2)。
  • 扩展区(D),共 222 字,其范围为:U+2B740 - U+2B81D。这是在2010年引进的(Unicode 6.0)。
  • 兼容汉字(1),共 302 字,其范围为:U+F900 - U+FA2D。
  • 兼容汉字(2),共 62 字,其范围为:U+FA30 - U+FA6D。
  • 兼容汉字(3),共 106 字,其范围为:U+FA70 - U+FAD9。来自北朝鲜。
  • 兼容汉字(4),共 542 字,其范围为:U+2F800 -U+2FA1D。来自台湾。

上述的统一汉字基本集是最重要的,特别是 20,902 个 GBK 汉字,大多数操作系统都可以正确处理这些汉字。其余汉字在有些操作系统中可能不能正确显示。

生成全部中日韩越统一表意文字

根据上面的讨论,我们就可以生成全部中日韩越统一表意文字了,相应的 C# 程序如下所示:

 1 using System;
 2 using System.Text;
 3 
 4 // 生成全部中日韩越统一表意文字
 5 sealed class UnihanCreator
 6 {
 7   static int [,] Groups = { // 75,617 合计 (Unicode 6.2)
 8     { 0x4E00,  0x9FCC  },   // 20,941 统一汉字基本集
 9     { 0x3400,  0x4DB5  },   //  6,582 统一汉字扩展区(A)
10     { 0x20000, 0x2A6D6 },   // 42,711 统一汉字扩展区(B)
11     { 0x2A700, 0x2B734 },   //  4,149 统一汉字扩展区(C)
12     { 0x2B740, 0x2B81D },   //    222 统一汉字扩展区(D)
13     { 0xF900,  0xFA2D  },   //    300 兼容汉字(1)
14     { 0xFA30,  0xFA6D  },   //     62 兼容汉字(2)
15     { 0xFA70,  0xFAD9  },   //    106 兼容汉字(3)
16     { 0x2F800, 0x2FA1D },   //    542 兼容汉字(4)
17   };
18 
19   static void Main()
20   {
21     var sb = new StringBuilder();
22     for (var i = 0; i < Groups.GetLength(0); i++)
23       for (var j = Groups[i, 0]; j <= Groups[i, 1]; j++)
24         sb.Append(GetUtf16Chars(j));
25     Console.WriteLine(sb);
26   }
27    
28   static char[] GetUtf16Chars(int n)
29   {
30     if (n <= char.MaxValue) return new char[]{ (char)n };
31     return new char[]{ (char)(0xD800 | ((n - 0x10000) >> 10)), (char)(0xDC00 | (n & 0x3FF)) };
32   }  
33 }

在 Arch Linux 的 Mono 环境下编译和运行:

work$ dmcs UnihanCreator.cs
work$ mono UnihanCreator.exe
一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗 ... 讛讜讝讞讟讠计订讣认讥 ... 䶯䶰䶱䶲䶳䶴䶵𠀀𠀁 ... 

是不是有很多不认识的字?

测试程序

下面是一个测试程序 UnihanTester.cs:

 1 using System;
 2 using System.Text;
 3 
 4 static class UnihanTester
 5 {
 6   static readonly Encoding GB18030 = Encoding.GetEncoding("GB18030");
 7  
 8   static void Main()
 9   {
10     Console.WriteLine("-Code Chars---- Unicode---- GB18030---- UTF8------- [--]");
11     foreach (var n in new int[]{ 0x3F, 0x25CB, 0x3400, 0x4DB5,
12       0x4E00, 0x9FA5, 0x9FA6, 0x9FCB, 0x9FCC, 0xF900, 0xFA2D, 0xFA30, 0xFA70,
13       0x20000, 0x2A6D6, 0x2A700, 0x2B734, 0x2B740, 0x2B81D, 0x2F800, 0x2FA1D })
14     {
15       var s = new string(GetUtf16Chars(n));
16       Console.WriteLine("{1,5:X} {2,-9} {3,-11} {4,-11} {5,-11} [{0}]",
17         s, n, GetCharsHexString(s),
18         BitConverter.ToString(Encoding.Unicode.GetBytes(s)),
19         BitConverter.ToString(GB18030.GetBytes(s)),
20         BitConverter.ToString(Encoding.UTF8.GetBytes(s)));
21     }
22   }
23    
24   static string GetCharsHexString(string s)
25   {
26     var sb = new StringBuilder();
27     foreach (var c in s) sb.AppendFormat("{0:X4}-", (int)c);
28     if (sb.Length > 0) sb.Length--;
29     return sb.ToString();
30   }
31    
32   static char[] GetUtf16Chars(int n)
33   {
34     if (n <= char.MaxValue) return new char[]{ (char)n };
35     return new char[]{ (char)(0xD800 | ((n - 0x10000) >> 10)), (char)(0xDC00 | (n & 0x3FF)) };
36   }  
37 }

在 Arch Linux 的 Mono 环境下编译和运行:

UnihanTester in Linux

运行结果还不错,大部分测试的汉字都能显示。U+10000 以上的字在 .NET Framework Class Library 的 Unicode (UTF-16) 编码中是使用两个 Char 分为高、低位代理表示的,也能正确显示为一个字符。

在 Windows 7 操作系统的 .NET Framework 4.5 下编译:

C:\work> csc UnihanTester.cs
Microsoft(R) Visual C# 编译器版本 4.0.30319.17929
用于 Microsoft(R) .NET Framework 4.5
版权所有 (C) Microsoft Corporation。保留所有权利。

运行结果如下所示:

UnihanTester in Windows 7

这下就有许多测试的汉字显示不出来了。而且 U+10000 以上的字作为两项显示了。

中日韩越统一表意文字的字形

这 75,617 字的字形可从 Unicode 网站的 Unicode 6.2 Character Code Charts 页面下载,具体如下:

work$ wget http://www.unicode.org/charts/PDF/U25A0.pdf
work$ wget http://www.unicode.org/charts/PDF/U3400.pdf
work$ wget http://www.unicode.org/charts/PDF/U4E00.pdf
work$ wget http://www.unicode.org/charts/PDF/UF900.pdf
work$ wget http://www.unicode.org/charts/PDF/U20000.pdf
work$ wget http://www.unicode.org/charts/PDF/U2A700.pdf
work$ wget http://www.unicode.org/charts/PDF/U2B740.pdf
work$ wget http://www.unicode.org/charts/PDF/U2F800.pdf
work$ ls -lh *.pdf
-rw-r--r-- 1 ben users  39M  8月 28 02:59 U20000.pdf
-rw-r--r-- 1 ben users 193K  8月 28 02:59 U25A0.pdf
-rw-r--r-- 1 ben users 3.2M  8月 28 02:59 U2A700.pdf
-rw-r--r-- 1 ben users 225K  8月 28 02:59 U2B740.pdf
-rw-r--r-- 1 ben users 586K  8月 28 02:59 U2F800.pdf
-rw-r--r-- 1 ben users 6.5M  8月 28 02:59 U3400.pdf
-rw-r--r-- 1 ben users  34M  8月 28 02:59 U4E00.pdf
-rw-r--r-- 1 ben users 682K  8月 28 02:59 UF900.pdf

看个例子:

Unihan : 2F800 

上图中的 U+2F800 是兼容汉字(4)中的字,它等价于 U+4E3D,是统一汉字基本集中的“丽”字。前面的测试程序在 Linux 中运行时,很聪明地使用这个等价的“丽”字来显示 U+2F800。

参考资料

  1. 维基百科: 中日韩越统一表意文字
  2. 维基百科: UTF-16
  3. Unicode: Unicode 6.2 Character Code Charts
  4. Unicode: Unihan Grid Index
  5. 博客园(银河): 浅谈 GB13000
  6. 博客园(Muse): 提取所有汉字
  7. 文化中国: 文献信息处理
posted on 2012-12-27 22:06 银河 阅读(...) 评论(...) 编辑 收藏