從 Thompson 的 Escape character 與 "成功\n" 談起

看板Programming作者時間18年前 (2007/03/11 19:01), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
> ==>發信人: 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
文章代碼(AID): #15y-5l00 (Programming)
文章代碼(AID): #15y-5l00 (Programming)