Fw: [讨论] Unicode (was: [问题] gcc对非英文…

楼主: LPH66 (-6.2598534e+18f)   2015-02-16 02:06:10
※ [本文转录自 C_and_CPP 看板 #1KuD_w8l ]
作者: LPH66 (1597463007) 看板: C_and_CPP
标题: [讨论] Unicode (was: [问题] gcc对非英文
时间: Mon Feb 16 02:05:42 2015
应该已经偏版题很多了, 不过还是提一下我所知的资料
(本文同步转录 Programming 版)
: → uranusjr: UTF-8 也只有保证“目前”可以表示所有 Unicode 字符 XD 02/15 20:36
: → uranusjr: 尤其现在的 UTF-8 规范把上限下修到 4 bytes, 总有一天 02/15 20:38
: → uranusjr: 还是会用完, 到时候再看看他们打算怎么办 02/15 20:38
: → PkmX: UTF-8 4bytes可以表示到U+10FFFF (17 * 2^16 = 1114112) 02/15 20:50
: → PkmX: Unicode 7.0也才定义113021个codepoints 要用完应该还很久XD 02/15 20:51
: → PkmX: 就算17个planes真的用完 UTF8照规律也可以延伸到使用5 bytes 02/15 20:55
: → frankhsu421: 顺带一提 这code在真的linux上跑会runtime error 02/15 21:09
: → frankhsu421: linux上uintmax_t没有比wchar_t大 02/15 21:10
: 推 LPH66: UTF-8 下修的原因是 Unicode 本来就定到 U+10FFFF 而已 02/15 21:17
: → LPH66: UTF-8 4byte 其实可以表示到 0x1FFFFF (32*2^16-1=2097151) 02/15 21:18
: → LPH66: 而 Unicode 只定到那里的原因是 UTF-16 的 surrogate pairs 02/15 21:18
: → LPH66: surrogate pairs 的最后一个组合 U+DBFF U+DFFF 表示的 02/15 21:19
: → LPH66: 就是 U+10FFFF 再上去的话 surrogate pairs 就不够了 02/15 21:19
: → uranusjr: 那是 UTF-16 的上限, Unicode code point 是无极限的 02/15 21:56
Unicode 最早最早是只有到 U+FFFF 的
(维基百科上有引用 Unicode 创立者之一 Joe Becker 在 1988 年发表的草稿文字
说是他当时认为 2^14 = 16384 个字应该够用了
因此将 Unicode 定为一个 16-bit 编码)
后来跟 ISO/IEC 10646 的合流才有把字码表延伸出去的想法
(ISO/IEC 10646 是订成一个 31-bit 编码
它的其中一个表示法 UCS-4 即是用一个 32-bit 整数去装这个编码)
也因此到了 1996 年的 2.0 才新增了 surrogate pairs 的机制表示 U+10000 以后的字
而这个 surrogate pairs 的自然上限即是 0x10FFFF
所以要说那是 UTF-16 的上限也没错, 因为 Unicode 原本就是个 16-bit 编码
之所以有"限定"下来一说可能是跟 ISO/IEC 10646 搞混了
因为被限定的其实是这个原本是 31-bit 编码的 ISO/IEC 10646
因为跟 Unicode 合流的关系才把自己的字码范围限在 0x10FFFF 以内
(这个"限制"应该不是明文限制, 只是两边的标准组织讲好这样
注意到虽然我上面说合流, 不过那只是共同制定字码相容的标准而已
Unicode 跟 ISO/IEC 10646 还是两个标准; Unicode 多了许多字符显示上的规定)
===
UTF-8 最早当它在一张餐巾纸的背面被写下来时
它的目标编码其实是 ISO/IEC 10646, 也就是那个 31-bit 的大编码
因此在 1993 年初它发表的时候, 一个字最多可以表示成 6 byte
是到了 Unicode 跟 ISO/IEC 10646 合流有了 U+10FFFF 的限制之后
才有了 RFC 3629 这一条 RFC 把 UTF-8 限制在 U+10FFFF 以下
(也就是说, 实际上是因为 ISO/IEC 10646 自我限定字码才有 RFC 3629 限定 UTF-8
而不是因为 UTF-8 定了限制才让字码限定在 U+10FFFF 的
RFC 3629 是 2003 年订定的, 那时已经是 Unicode 4.0 了)
UTF-8 限定在 4-byte 以内是这个 RFC 的自然结果
而且也不是任意 UTF-8 的 4-byte 顺序都是合法的
如我上面推文所说, UTF-8 的 4-byte 最多可以到 0x1FFFFF
RFC 3629 规定这段范围里超过 0x10FFFF 的都是不合法编码
===
所以如果万一真的用完了要延伸的话
应该会沿着 ISO/IEC 10646 原先定义的方向下去延伸
问题只有 Unicode 这边要怎么延伸字码表示而已
UTF-8 倒是不必担心, 原先的设计就足够用到 31-bit
(到时大概会有另一个 RFC 出来说取代 RFC 3629 这样)
===
至于现在 Unicode 里定了多少字?
Plane 0 BMP (U+0000~U+FFFF) 虽然还有一点点空位, 基本上可以算是满了
Plane 1 SMP (U+10000~U+1FFFF) 包含一些古代语言(eg.线型文字)跟哩哩扣扣的符号
大概只用掉这块的两成不到
Plane 2 SIP (U+20000~U+2FFFF) 包含古中文字、罕用中文字
这块使用率目前还不错, 已经用掉超过七成
很多罕用字大都能在 Ext.B (U+20000~U+2A6DF) 里面找得到
Plane 3 预计是要留给像甲骨文、金文、小篆之类的字
不过现在 (as of Unicode 7.0) 还是空空的就是了
Plane 4~13 现在还是杂草一片
Plane 14 只有定义了大概百来个控制字符
Plane 15~16 则是更大一块的 private use area (约有十三万个字的空间的造字区)
所以其实这一百多万个字码要用完个人觉得还很久就是了
而且 Unicode 在定字时其实多少会简单分析一下到底基本的"字"是什么
所以字码并不会太过膨胀 (可以看印度文就知道)
相对的最占空间的字就是做的没有这么彻底的中文字
不过就算这样, SIP 现在也才填了个七成而已, 要到占满所有字码真的还早

Links booklink

Contact Us: admin [ a t ] ucptt.com