看板Programming
标 题从 Thompson 的 Escape character 与 "成功\n" 谈起
发信站中央大学松涛风情资讯站 (Sun Mar 11 14:11:57 2007)
转信站ptt!ctu-reader!ctu-peer!ctu-gate!news.nctu!news.ncu!news.csie.ncu!Ever
> ==>发信人: [email protected] (想和你去把把风), 信区: programming
> ※ [本文转录自 Google 看板]
> 作者: davidyu (davidyu) 看板: Google
> 标题: Re: [讨论] Gmail收外部信…怎麽放心把密码交出去呢?
> 时间: Sat Feb 24 12:19:19 2007
> 讲到 trust, 就不得不提一下这个很有名的故事:
> 故事的主角是 Ken Thompson,他是 Turing Award 得主,也是发明 C 语言和 UNIX 的
> 关键人物,目前在 Google 工作(这样就和这个板有关了 ;-)。
> 这个故事是这样的。Thompson 写过一个很有趣的程式,是一个特别的 C compiler。如
> 果你对 compiler 的知识还算熟悉的话,应该知道 C 的 compiler 是可以用 C 来写的
> 这是一个鸡生蛋,蛋生鸡的问题,不过我们的确是用 C 来写 C compiler。
> Thompson 的 compiler 之所以特别,是他在其中偷偷藏了一个 bug。UNIX 有一个程式
> 叫 login,它是负责核对使用者帐号和密码的程式。Thompson 的 compiler 如果发现它
> 在 compile 一个 UNIX 的 login 程式时,它会在比对密码的时候,偷偷加入一笔万用
> 密码。如此一来,用这个 compiler 产生出来的 UNIX,都会有这个「漏洞」在。你会说
> 这个只要检查 compiler 的程式码就可以发现了。没错,所以 Thompson 的 compiler
> 还有一个神奇的功能。这个 compiler 如果发现它在 compile 一个 compiler 的时候,
> 它会把它本身的这个「神奇功能」放到 compiler 里头,所以用这个 compiler compile
> 出来的 compiler (我知道这有点难懂 XD)也都会带有这个神奇功能。之後,他再用
> compiler 把本身自己 compile 一次後,就可以把神奇功能从程式码里面隐藏起来,只有
> 从 binary 才看的出端倪。
> 这会造成一个问题,就是你即使有原始码,你也没办法确保你的程式是可以信任的。你
> 要能够确定你的程式是可靠的,唯一的办法就是全部从头来。如果你把这个问题过度延
> 深,你就会发现你可能要从 CPU 的电晶体开始设计,才有办法「保证」你的程式是完
> 全符合你的意思在执行。
> 所以,信任,不是见简单的事。
> 喔.....我还想补一句「电脑是很危险的,你还是回去用算盘吧」...XD
> p.s. 详细的故事可以在这边找到 http://www.acm.org/classics/sep95/
Thompson 在 ACM 的这篇文章, 举了 \VT 这个例子, 他是假设要在
C 语言增加一个新的特殊符号功能该如何 patch 进旧的 c-compiler source
program 让负责编译的 旧compiler "不排斥(跟生物的异体植入问题类似)",
再以"接枝"的手法产生 新compiler , 而这 新compiler 的接枝部份还进一
步能 "区分" 旧compiler program 自动将新增功能的片段程式移入, 使之
成为一个 新compiler source program. (相当於病毒植入细胞的遗传基因,
还能区别异同, 改造其他旧细胞的基因使之趋同, 实例是电脑病毒).
先不谈这个扩充功能(extended machine)的问题, 先问: 电脑程式语言
碰到中文BIG5码是否能区分监别, 加以不同对待(这算扩充功能吧 !)的问题.
例如:
char*f="敬祝成功\n 宏图大展\n";
main()
{
printf(f,10);
}
得到的显示结果是:
敬祝成功n 宏图大展
而不是
敬祝成功
宏图大展
================
这种麻烦怎麽解决 ?
法一: 针对 "\" 做答案, 对中文码做 pre-processing , 功 的BIG5码右半
byte 就是 "\" , 补成 "\\", 也就是改为
char*f="敬祝成功\\n 宏图大展\n";
可是列印原始程式时, 就会误以为原文是要
敬祝成功n
宏图大展
做了前处理的原始资料就多了 "\" , 假如一时不查就再把这处理过的原始
程式送给别人看, 或电脑将这个处理过的字串再送(或被拿去使用)给别的
程式, 再假设那个程式认得中文码, 因之对功的右半 "\" 不做 ESC 处理,
那就是整个前处理过的字串多了一个 "\", 收送双方因之不一致.
前处理是因为能识别是中文BIG5, 所以加了"\"给不懂中文码的 compiler
请其避开, 但不懂中文的 c-program 在执行中送那串中文字串给另一个後
续程式, 那个程式可能有能力识别, 但也可能无能力识别, 後续程式因为
不知道有"前处理的额外补加"就又弄乱了套.
那就把 "识别中文能做类似前处理避开误动作" 这个功能做进新的
c-compiler , 所以原始程式仍维持
char*f="敬祝成功\n 宏图大展\n";
这个式样.
但为了容易扩充, 实作的执行码(新功能)可能是相当於利用旧的功能合成,
因此还是用了 pre-processing 的概念.(这新功能与旧功能之间不是采正
交 othogonal 的隔离想法)
char*f="敬祝成功\\n 宏图大展\n";
但在转送这个字串给别的後续程式用的时候, 因为不知道後续程式的性能,
就只好对中文字串做 post-processing, 还原为原始程式样式"
char*f="敬祝成功\n 宏图大展\n";
但问题来了, 後续程式的 compiler 未必认得中文耶 !
Ken Thompson 的文章就是 感染其他旧的 c-compiler 让他认得 BIG5 中文.
但问题又来了 !
汉字可不是只有你家在用, 日韩大陆的汉字怎麽办 ?
--
◎ Origin: 中央松涛站□bbs.csie.ncu.edu.tw From: 140.115.6.234