作者horngsh (要公理要正义)
看板C_Sharp
标题[转录]Re: [问题] Big5跟UTF-8不需要考虑endian跟相容ASC …
时间Fri Jan 30 13:39:09 2009
※ [本文转录自 Programming 看板]
作者: LPH66 ((short)(-15074)) 看板: Programming
标题: Re: [问题] Big5跟UTF-8不需要考虑endian跟相容ASC …
时间: Mon Jan 26 17:52:24 2009
就我对字元编码的所知来回答看看
※ 引述《zlw (洞房不败)》之铭言:
: 大家好
: 我对於 Big5 似乎不需要考虑 endian 这点感到疑惑,想请教一下。
: --
: 比如AB两个字,其 ASCII Code 为 41 42 (16进位),而 Unicode codepoint 为 U+0041
: 跟 U+0042。
: 如果 Little Endian 的电脑存一份内容为AB的文件,编码成UTF16,因为 UTF16 基本单位
: 是 2 Bytes,所以不考虑BOM情况下,内容最後会成 41 00 42 00 (16进位)
: 当传送到 Big Endian 的电脑时,解读出来的内容就变成 U+4100 U+4200 两字,而非AB
: --
: 我的问题是,Big5也以 2 Bytes 为一个字的基本单位,但似乎不需要考虑endian。这是
: 因为Big5向下相容ASCII,所以CPU只会当成一堆ASCII去存,跟UTF-8一样,基本单位变成
: 1个byte 才可以不用考虑endian?
这部份可能是对的
由於 unicode 本身并不是 DBCS/MBCS 的编码
不需要相容於原有的编码之中
因此才必须自己决定要用什麽方式来储存编码
(因其每个编码的大小是 16-bit = 2 byte
等於你要想办法存一个 C 语言中的 short 那麽大的数字
当然要考虑 endianness 了)
而 DBCS/MBCS 的编码为了要能相容於旧编码 (在此即ASCII)
因此需要有一个头的机制来分出从哪一个开始
当然基本单位就变成和旧编码 (ASCII) 一样是 1 个 byte 了
以 UTF-8 的机制为例就是看到一个 byte 范围在 0xC2~0xF4 之间表示一个头的开始
而 Big-5 则是 > 0x7F 做为头这样
所以严格说起来 UTF-16 也可以算是 D"B"CS
(或许该改叫 DCCS, Double-Codepoint Character Set?) (←这是我胡诌的词别当真XD)
因为 UTF-16 有所谓的 surrogate pair 的设计 用来表示 U+10000 以上的字元
而这个设计是以 U+D800~U+DBFF 做为头 U+DC00~U+DFFF 做为尾的设定
和 DBCS 其实还满像的
只不过这里的基本单位是 2 byte 因此还是得考虑 endianness
(也就是为什麽会分出 UTF-16LE UTF-16BE 的原因了)
: 等到开启文件内容,比如为 A7 41 41 (16进位) 时,记事本逐一搜寻发现A7大於ASCII
: 理论上最大的7F时,才更改判别此文件是所谓的 DBCS?(这我不太懂,不确定)
: 然後因为Windows当时设定,在控制台->地区及语言选项->进阶->非Unicode程式的语言
: 里面是设成中文(台湾),所以才进一步判定为Big5编码,并且显示出繁体中文「你A」来
: 整个的流程、原理是这样吗?
这要稍微扯到 Windows 的判定规则了
没有特别处理的话 就我所知
Windows 是将 native 的编码视为所谓 "ANSI" 编码
(就是记事本的 "ANSI" 存档选项)
这 native 的编码应该就是相容於过去所谓的 code page 的东西
像 Big5 => CP950, GB2312 => CP936, Windows的西欧字母 => CP1252 这样
也因此系统里会留着一份各个 code page 的对照表
(C:\Windows\System32\C_xxx.nls 就是了
UAO (aka. unicode补完) 也是改动这里的 C_950.nls)
在需要时 (下面会提到) 会自动抓这里的对照表来转码
而记事本其实它是一支 unicode 程式
(你可以在记事本里打一些这里打不出来的字符和组合
例如你可以在同一篇文件中参杂繁中简中日韩四种文字都没问题)
只是它内建有 unicode 侦测 当开档的时候会自动侦测它是不是 unicode
如果它判定是 UTF-16LE/UTF-16BE/UTF-8 三者之一的话
就会以那种格式来开启文件
否则就会判定为 ANSI 才会让系统以目前的预设编码来找 code page 转码
这时才会去看系统设定非 unicode 程式用什麽编码来找
(以我这台 Vista 的选项来说
中文(繁体,台湾) 就是 CP950 同理 中文(简体,中国) 就是 CP936 )
顺带一提, UTF-8 也是一个 MBCS 的编码
所以它也有自己的 code page 号码: CP65001
不过因为 UTF-8 稍微特殊 它并没有对应的 C_65001.nls 在系统里
而是直接在系统程式里解决掉了
: --
: 另外有些不支援Unicode的软体,平常只能读英文及繁体中文的目录,但是把「非Unicode
: 程式的语言」这个设定改成韩文後,就能开启韩文命名的目录。我想查这部份的资料,
: 为什麽会有这种状况,以及要如何改善,想请教有什麽关键字?
: 谢谢大家。
这单纯就是转码的问题而已
原因只是因为 Big-5 没有韩文
程式要向系统抓目录 系统看到程式使用了非 unicode 的(旧式) API
就把抓来的名字转成 "ANSI" 编码送给程式
这里的 "ANSI" 编码一样视控制台的那个设定而定
那因为 Big-5 里没有韩文 所以韩文目录就变成 ????? 了
那当程式要开启叫做 ????? 的目录时 因为程式给系统的是 "?????" 这个名字
系统自然回说找不到目录 所以开启失败
当你把设定改成韩文後
系统抓来的名字转成 "ANSI" 编码时就会去抓 EUC_KR (CP949) 来转码
而 EUC_KR 里面就有韩文 所以程式收到了正确转成 EUC_KR 的韩文字
再用这些韩文字向系统要求开启目录
系统从非 unicode 的 API 收到的字串就由 EUC_KR 转回 unicode
就正确的开启了目录
也就是说, 系统在发现程式和他沟通是使用旧的 API 时
就知道这支程式想要旧的行为
因此会自动把送来的字串先过一次转码转成 unicode 再送给後端
後端回来的字串再过一次转码转成 "ANSI" 编码才送回去给程式
这就是上面提的"需要时转码"那个"需要时"
而控制台的设定就是设定这里要转成哪一个 code page 而已
--
[LPH] Oops, your OOP's a problem? 说:
你现在还是看不到狗?
************* 说:
看得到 只是 他们不会跑 就一直呆呆在那边 一直在起点
[LPH] Oops, your OOP's a problem? 说:
你要按"ㄅㄧㄤˋ"它们才会跑啊@@"
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 122.254.20.82
1F:推 jeonjh:用心的文章... 122.124.129.74 01/29 11:45
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.126.240.23