從 Thompson 的 Escape character 與 "成功\n" 談起
> ==>發信人: HowLeeHi.bbs@ptt.cc (想和妳去把把風), 信區: 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
Programming 近期熱門文章
PTT數位生活區 即時熱門文章