ITHOME 必看!IT好書101

http://www.ithome.com.tw/itadm/article.php?c=63952&s=1
1.The Mythical Man-Month(人月神話:軟體專案管理之道)
王建興 ★★★★★︰軟體工程領域的經典書籍,書中所談及的許多軟體專案問題,至今仍然困擾著軟體開發團隊,但其實大師早在書中便已指出方向。
>>點我看圖

2.Advanced Programming in the UNIX Environment(Advanced Programming in the Unix Environment國際中文版)
陳昇瑋 ★★★★★︰Unix programming 的經典書
>>點我看圖

3.The Art of Computer Programming系列
上官林傑 ★★★★★︰經由大師的指點,深入瞭解什麼是programming。
>>點我看圖

4.Mastering Regular Expressions
王森 ★★★★★︰不管在系統管理,或是軟體開發上,Regular Expression可以完成的事情超乎許多人的想像,尤其幾乎每種語言都內建支援的函式庫,更讓這個歷史悠久的技能,持續默默地支援IT從業人員。>>點我看圖

5.Effective UI
王森 ★★★★★︰自從iPhone受歡迎以來,使用經驗(User eXperience)受到許多人的重視,本書從比較不技術的層面引導讀者甚麼叫做User eXperience,讓大家可以更容易拋開技術導向的思維,真正從用戶的立場來思考軟體設計。
>>點我看圖

6.Introduction to Algorithms
王建興 ★★★★︰演算法是程式設計的根本基礎,本書對於演算法的基本觀念,以及常見、常用的演算法都有十分完整的介紹。
上官林傑 ★★★★★︰鍛練深厚的演算法基礎,幾乎是全世界學習演算法的資訊人都不會錯過的一本書,而且國內大專院校的資訊系幾乎都以本書作為演算法課程的教科書。它不僅是說明各種問題的演算法,更會介紹如何分析演算法複雜度,以及演算法設計策略。
>>點我看圖

7.Computer Algorithms
陳昇瑋 ★★★★★︰演算法自學經典書
>>點我看圖

8.Fundamentals of Data Structures in C
陳昇瑋 ★★★★★︰資料結構自學經典書
上官林傑 ★★★★★︰資料結構的基礎,資料結構對於程式寫作是很重要的工具,它不僅能夠讓讀者瞭解如何有效地擺放記憶體中的資料之外,也可以瞭解到它如何輔助實現各種演算法的設計。
>>點我看圖

程式設計-軟體開發流程

9.Design Patterns: (物件導向設計模式)
王建興 ★★★★★︰設計模式已經成了當今程式設計者不可或缺的觀念和工具。本書可謂設計模式書籍中最為經典的一本,任何有興趣於設計模式的程式設計者都不應該錯過。
陳宏一 ★★★★︰就物件導向設計而言,本書已經屬於聖經級的水平,內容需要細細品味,時而溫故而有知新之感觸。
>>點我看圖

10.Code Complete(軟體建構之道)
陳昇瑋 ★★★★★︰本書教你如何嚴謹地寫程式,以及如何善用偵錯工具來避免及找出錯誤。
王森 ★★★★★︰集結了微軟在軟體開發上的實務經驗,這本書也出現在許多大公司RD部門的書架上。
>>點我看圖

11.Refactoring(重構:改善既有程式的設計)
王建興 ★★★★★︰重構技巧在敏捷的軟體開發方法中扮演著十分關鍵的角色,能協助程式設計者修正隨時間過去而日漸敗壞的程式碼架構。而本書正是公認介紹重構技巧最為經典的一本書。
>>點我看圖

12.Code Craft(編程創藝:編寫出卓越的程式碼)
王建興 ★★★★★︰大多數身為一名程式設計者在工作中會涉及到的議題,小到變數如何命名、大到團隊如何協同合作,本書都提供了全盤的介紹及論點。對程式設計者而言,是本值得推薦的好書。
>>點我看圖

13.Applying UML and Patterns(UML 與樣式徹底研究)
陳宏一 ★★★★★︰談論UML主題的書不下百種,筆者還是覺得本書有一站購足的體驗!無論是流程及工具均交代得十分清楚,配合實例說明,讓你對UML方法論印象更為深刻。
>>點我看圖

14.Continuous Integration- Improving Software Quality and Reducing Risk
陳宏一 ★★★★★︰軟體工程生產自動化在這本書有完整介紹,並提供了不少業界已經被採用的Open Source工具,將理論應驗於實際工作上。
>>點我看圖

15.How We Test Software at Microsoft(軟體測試之道-微軟測試團隊的成功經驗、方法與技術)
王森 ★★★★︰微軟累計超過25年以上的軟體測試經驗,全部都在這本書上一次攤開,除了可以更了解軟體測試的重要性,也能夠讓讀者對軟體品質有更深入的認識。
>>點我看圖

程式設計-Web

16.Head First HTML with CSS & XHTML(深入淺出HTML、CSS與XHTML)
林信良 ★★★★︰在高互動性網頁風行的這個世代,Web程式開發前端不斷有各種精妙技術出現,然而基於網頁的本質是不變的,若你不了解 HTML 版本遷移所帶來的意義,不了解 HTML 4 標準的主要目的是什麼,不了解何謂結構與樣式分離,這本書是個有趣且條理分明的開始。
>>點我看圖

17.Designing Web Interfaces
上官林傑 ★★★★︰從案例及 patterns 中學習 Web 介面的設計及思考。本書採全彩印刷,從許多知名的網站中挑出設計優良的部份做介紹,並且將許多網頁操作動線歸納成一個個 patterns,提供讀者在設計網頁時的參考。
>>點我看圖

18. JavaScript:The Good Parts(JavaScript優良部份)
陳宏一 ★★★★★︰JavaScript已經是現今Web技術不容忽視的一環,本書教你如何撰寫良好的JavaScript程式,以對照方式說明,方便讀者了解其中奧妙,才能趨吉避凶。
上官林傑 ★★★★★︰重新認識 JavaScript 這個程式語言。JavaScript 在現代網頁開發佔有一個十分重要的地位,然而過去的開發者不見得徹底地瞭解JavaScript 的設計,本書除了介紹 JavaScript 好的設計之外,還有更多與其它語言的不同之處,試圖讓讀者更瞭解這個語言以寫出好的 JavaScript 程式。
>>點我看圖

19.jQuery in Action(jQuery 實戰手冊)
陳宏一 ★★★★︰此書以導引式寫法,完整介紹jQuery常用及進階的實務作法,以情境輔佐實例程式碼說明,便於初學者閱讀。
>>點我看圖

20.jQuery Cookbook
陳宏一 ★★★★★︰本書內容為問題導向陳述架構,針對各個主題引領讀者進入jQuery的世界,內容提供明確的jQuery功能說明及解法,讓讀者再不快速上手也難!
>>點我看圖

21. Learning Python 4th Editon(Python 學習手冊)
林信良 ★★★★︰Python 3 是個重要的版本,它幾乎重構了Python 這門語言,它的許多特性回饋至 Python 2.x,藉由 Learning Python 4e一書,你可以同時了解 Python 3 與 Python 2.6 的不同,同時也思考,為何 Python 3 會納入那些新特性,從而了解作為一門解決問題的語言,該有的要素為何,作為一個 Python 新手,也可以藉由本書,了解到 Python 中一些有趣的特性,像是 Function、Decorator、Descriptor、Meta programming 等。
>>點我看圖

22.Complete Web Monitoring
陳宏一 ★★★★︰本書提供全方位的角度,從使用體驗面、系統效能面、數據分系析面,各個擊破,提醒在網站營運時需留意的重點,制訂KPI管控,進而改善網站整體運作。
>>點我看圖

23. High Performance Web Sites
上官林傑 ★★★★★︰學習如何調整 web 前端效能。是Steve Souders在 Yahoo! 工作時寫的書,其實High Performance Web Sites和Even Faster Web Sites這兩本書,我覺得根本就是上、下或者說是I、II,寫作的精神跟概念也幾乎是一模一樣(而且還是同一個作者)。
>>點我看圖

24.Even Faster Web Sites
陳宏一 ★★★★★︰Web網站效能直接影響到一個網站的成敗,本書收集了來自知名網站的專家經驗,提供可量化之實用工具及測量方法,讓你有效改善自家網站的效能。
上官林傑 ★★★★★︰Steve Souders 在 Yahoo!任職期間主導了知名網頁效能調校工具--Y!Slow專案的開發,後來轉職到 Google 任職時則推出了 PageSpeed 這套工具。這本是他在 Google 工作時寫的。除此之外,他還在 Stanford 大學開設網頁效能的相關課程,這本書會介紹不同瀏覽器的特性,以及他們實作標準的特色,讓讀者從各種經驗中學習如何提升網頁前端的效能。
>>點我看圖

25.Web Operations: Keeping the Data On Time
陳宏一 ★★★★︰就談論Web網站系統營運的課題,本書算是第一本,要確保一個網站系統能營運順暢無誤,許多執行上的細節必須憑靠多個單位的協力合作,這裡提供了Google、Yahoo、Microsoft等大型網站專案的經驗分享,值得一讀。
>>點我看圖

26.Web Analytics 2.0
陳宏一 ★★★★★︰分析訪客對於網站的行為,有助於更了解你的客戶,掌握他們真正的需求,提供適時適性的產品及服務內容。
>>點我看圖

27.Website Optimization: Speed, Search Engine & Conversion Rate Secrets
陳宏一 ★★★★★:經營網站,SEO已經是不容忽視的必要課題,本書從網站資訊架構,到網頁面細節定義,提供不少價值性的建議做法,為提供SEO工作者的最佳參考書籍。
>>點我看圖

28.The Art of Community: Building the New Age of Participation
陳宏一 ★★★★︰從Facebook的崛起,社群經營已可視為企業活動,從社群建立,如何讓身為社群自成一烏托邦,達成完美生態平衡,本書有著相當精闢的論述,為少見社群管理之專書。
>>點我看圖

29.Building Web Reputation Systems
陳宏一 ★★★★★︰簡單按一個「讚」,就能表示你對事物的看法,使用者點評網站提供足夠客觀的使用者經驗資訊,解決使用者在生活上的大小事,而此類型的網站應如何設計運作?本書有完整的解答!
>>點我看圖

程式設計-C

30.The C Programming Language(C 語言程式設計)
王建興 ★★★★★︰本書無疑是 C 程式語言的聖經。除了介紹 C 語言的特色,本書中所有的程式範例也足夠經典,示範了 C 語言的真正精神所在。
陳昇瑋 ★★★★★︰C 程式語言經典書。
>>點我看圖

31.C名題精選百則-使用C語言-技巧篇
陳昇瑋 ★★★★★︰居家的演算法實作練習。
>>點我看圖

32.C++ Primer Plus(C++ Primer Plus 5/e中文豪華版)
陳宏一 ★★★★︰書中除了介紹強調了與C程式語言不同的物件導向觀念,從最基礎的觀念建立起,是一本適合初學者的自學手冊。
>>點我看圖

33.Effective C++(Effective C++國際中文版:改善程式技術與設計思維的50個有效作法)
陳宏一 ★★★★︰此書作者將所學經驗歸納出五十多項黃金實務法則,讓C++程式撰寫的同好們在設計思維上能更上一層樓,絕對是一本不可多得的好書。
>>點我看圖

34.Thinking in C++(Thinking in C++ Second Edition 中文版)
陳宏一 ★★★★★︰就C++程式設計領域而言,可視其為架上必備之工具書,內容涵蓋完整,且針對每個章節都有相當深入的研究,由下到上的敘寫方式,協助讀者建立正確紮實的程式觀念。
>>點我看圖

35.Programming — Principles and Practice Using C++
上官林傑 ★★★★★︰大師教你怎麼把 C++寫好。本書的作者正是發明C++語言的人,至今仍然主導 C++的規格發展。由設計者將C++的使用方式,以及各種特色整理成冊,讓讀者瞭解怎麼使用這個語言來寫作程式。>>點我看圖

程式設計-Mobile

36.Programming the Mobile Web
陳宏一 ★★★★★︰智慧型手機的普及使得行動上網已經是時勢所趨,而本書介紹各式平臺及開發方式,對於初嘗手機開發的同好們,可以更快速上手。
>>點我看圖

37.Tapworthy – Designing Great iPhone Apps
王森 ★★★★★︰從本書中可以一次吸收iPhone眾多優秀Mobile Apps的設計,而這些優秀設計不只可以應用在iPhone上,一樣可以應用在Symbian、Android與Windows Phone 7。
>>點我看圖

38.Building iPhone Apps with HTML, CSS, and JavaScript: Making App Store Apps Without Objective-C or Cocoa
陳宏一 ★★★★︰對於已熟悉網頁技術,又想嘗試玩玩iPhone應用程式開發的人,這本書讓你可以循序漸進地體會開發iPhone應用程式的樂趣.。>>點我看圖

程式設計-.NET

39.WPF 4 Unleashed
王森 ★★★★★︰WPF是微軟未來10年的重要技術,從Surface的開發,到Silverlight及Windows Phone 7,全部都是以WPF為基礎。本書由WPF開發團隊的工程師親自執筆,全彩印刷,更能在閱讀時充分了解XAML的精髓。
>>點我看圖

40.C# 4.0 in a Nutshell
王森 ★★★★★︰目前可見學習C#最完整的一本書,針對給初學者設計,尤其在講解LINQ的時候,作者還自製了經典的LINQPad做為教學用,讓讀者可以更容易理解LINQ的運作機制,實屬少見對技術深具熱情的作者。
>>點我看圖

41.C# in Depth(精通C#)
王森 ★★★★★︰雖然作者寫完第一版之後,就去Google當工程師了,但是依然繼續寫第二版,這種熱情誰能有呢 🙂
>>點我看圖

42.CLR via C#, 3rd Edition
王森 ★★★★★︰大師著作,從裡到外完整剖析Common Language Runtime的運作方式,並解釋了許多在.NET上看起來簡單可以做到的事情,究竟經過了多麼巧妙的包裝,讓人大呼過癮。
>>點我看圖

43.Head First C#(深入淺出 C#)
陳宏一 ★★★★︰秉持Head First系列輕鬆詼諧的風格,在談論C#的眾多書海中,此書應屬值得參考的入門書之一。
>>點我看圖

44.ASP.NET MVC 2 開發實戰
陳宏一 ★★★★︰提供ASP.NET初體驗的網站開發人員不錯的學習手冊,作者深入淺出,從基本觀念帶到技術,最後談實務面的運用,也一併提到MVC的設計觀念,讓讀者在程式撰寫同時,也能兼顧良好的設計架構。
>>點我看圖

45.ASP.NET 3.5 最佳實務講座 Using Visual C#
陳宏一 ★★★★︰以初學者的角度從程式語言的概念開始,探討網站應用程式最常使用的Web Form與ADO.NET資料庫相關技術,以及將頁面華麗化的Ajax開發方式,足以讓有心想使用ASP.NET技術開發網站的同好們快速上手,作者在微軟技術領域已有多年實務經驗,閱讀本書必然在應用上有所助益。
>>點我看圖

程式設計-Java

46.Thinking in Java(Thinking in Java 4/e中文版)
王建興 ★★★★︰從物件導向的觀念到 Java 程式語言的特色,以及 Java 程式庫的應用,本書都做了最全面也足夠深入的介紹及探討。
陳宏一 ★★★★︰Java至今已推出第四版,無庸置辯地仍然處於Java界的聖經不敗地位,閱讀本書不僅是會用Java來寫程式,而是不斷去探討所用的細節,細細體會個中奧妙,較適合已經有經驗的Java開發人員。
上官林傑 ★★★★★︰這本書讓 Java 開發者瞭解到 Java 語言的設計思維,然後再以此思維出發來撰寫 Java 程式碼。讓你巧妙地運用 Java 語法以及它的套件,寫出好的 Java 程式。
>>點我看圖

47.Effective Java Programming Language Guide
陳宏一 ★★★★︰Java本書提醒了你在撰寫Java程式時,所應避免的壞習慣,這點很重要,很多日後的系統問題,都是這些點滴積累而造成。
上官林傑 ★★★★︰本書針對各種使用Java函式庫時要注意的效能部份作介紹,並且提供更有效率的寫法,當你已經會寫 Java 程式之後,這本書將會讓你寫出更有效率的程式碼。
>>點我看圖

48.Java Puzzlers(Java Puzzler中文版-陷阱、錯誤與死角)
陳宏一 ★★★★︰魔鬼都在細節裡,Java程式要怎麼寫,才不會造成日後的遺憾,本書內容會讓你在閱讀的過程中驚喜連連。
>>點我看圖

49.Head First Java, Second Edition(深入淺出 Java 程式設計)
陳宏一 ★★★★★︰以活潑的方式介紹Java程式設計,深入淺出帶你進入Java的世界,適合初次接觸Java的新手。
>>點我看圖

50.Core J2EE Patterns: Best Practices and Design Strategies
陳宏一 ★★★★︰提供多層式設計架構的範本,搭配範例程式,讓你更能領會這些設計精神,如何透過程式碼來達成最佳實踐。
>>點我看圖

51.Programming in Scala
林信良 ★★★★★︰姑且不論Java創始者James Gosling 與 Groovy 創始者 James Strachan對Scala這門語言的推崇,透過這本書所獲得的,並不僅是習得 Scala 這門語言,也學習到許多解決問題的方式,像是Closure、Immutable object、Functional programming等,如果你是個 Java programmer,更可以從這本書中,反過來了解Java許多優良與不優良的部份,或了解更多 Java 中特性的設計要點,像是 Generics 等。
>>點我看圖

系統管理

52.Hyper-V 虛擬化技術101問
threesecond ★★★★★(2010)︰這本書也是我相當推薦的實戰書,坊間介紹 Hyper-V 入門的書已經很多了,但障礙排除的書卻極少,新手入門時遇到問題就無解了,這本書列出101個安裝Hyper-V經常遇到的問題,建議先實作過幾次Hyper-V以後再來讀本書,比較容易體會。
>>點我看圖

53.深入Windows 核心- Windows Internals – 第五版
threesecond ★★★★★︰這本是Microsoft官方支援的教材,中文版堂堂邁入第五版,內容推進到Windows Vista 與Windows Server 2008,詳解作業系統底層的架構與各項技術,和市面上的入門書完全不同,這本書相當的扎實硬派,是有心精通 Windows 作業系統的人必讀的好書。
>>點我看圖

54.Windows XP Embedded 系統應用手冊
threesecond ★★★︰這是中文書裡唯一的一本 Windows XP Embedded 專書,如果要靠自學來入門的話,這本是必備的,事實上 Windows XP Embedded 入門門檻極低,難在後續的元件選擇,如果有一本好用的入門書,很快就能踏入 Embedded 的領域,這本可推薦。
>>點我看圖

網路管理

55.資料通訊與佈線設計
threesecond ★★★★★︰結構化佈線必讀的硬底子好書,也是台灣機房規劃權威ZMAN推薦必讀的書。可參考http://phorum.study-area.org/index.php/topic,41038.html。這本的原作是The Complete Guide to Network Wiring,中文版為第3版,雖然翻譯書讀起來比較吃力,但肯定是提升功力最快的方法。
>>點我看圖

56.網管員必讀-網路故障排除手冊
threesecond ★★★★︰這本書完全在講各種意外狀況的排除,市面上的書多半著重理論或基本操作步驟,很少有講實戰運用的,讀這本之前當然必須先具備各方面基礎網管知識,若已經在網路管理上有障礙排除經驗的話,讀這本書會比較有體會,不然只是鴨子聽雷而已。
>>點我看圖

57.CACTI監控系統實戰白皮書
PowerOp ★★★★★︰自由軟體網管系統,我主要是玩OpenNMS ,而 CACTI因為有了 cactiEZ 這個把 CentOS + CACTI一次裝好的懶人包,吸引了不少使用者,這本中文書作者在證券公司資訊部門任職,將數年實戰經驗跟大家分享,不可錯過!
>>點我看圖

58.Wireshark網路協定分析與管理
threesecond ★★★★︰Wireshark是每個學習TCP/IP與封包分析者都必用的軟體,但以前市面上沒有一本書專講Wireshark,使用者只能辛苦的讀英文手冊,或者找論壇上零散不齊全的教學,現在有這本書了,對學習者有非常大的幫助。內容也相當扎實,值得推薦。
PowerOp ★★★★★︰如果要做網管,網路封包的工具多少要懂一點。此書小問題不少,但日文原著的目標明確(向初學者介紹這個強大的工具),加上又是第一本中文書,整個看下來,對於應用的場合,以及使用時可以有哪些變化,還是能有一個基本的了解。
>>點我看圖

59.Routing TCP/IP, Volume 1 & 2
陳廣融︰經典、classical bible。
>>點我看圖

60.Network Mergers and Migrations: Junos Design and Implementation
陳廣融︰一本奇書,如果要執行大型網路的整合,可以參考。
>>點我看圖

資訊安全

61.Microsoft, Unix及Oracle主機與網路安全
threesecond ★★★★★︰這本書除了介紹各種平臺系統的漏洞與風險以外,還以大篇幅詳細介紹漏洞偵測的方法、風險評估、安全策略、人為因素控管等多個層面,不僅僅是局限於軟體層面而已,也是市面上少見的實戰經驗分析的書籍。
>>點我看圖

62.The Tao of Network Security Monitoring
陳彥銘 ★★★★︰網路安全監測是屬於知易行難的一部分。光是佈置 IDS/IPS 不夠用,還需要完整的監控才行。
>>點我看圖

63.No Tech Hacking
楊伯瀚 ★★★★︰與一般課程所強調的郵件詐欺與網站釣魚不同,作者將本身所受過的忍者訓練應用在實務上,以非常實際的案例探討各種社交工程攻擊技術。從最根本的人因危險概念開始,到針對生活環境上的惡意利用,包含尾隨、偷窺、翻找垃圾和各種實體安全上的漏洞。書中實例十分生動且讓人印象深刻,即使是非資安從業人員也能輕鬆從中了解生活中受到攻擊的危險,對個資外洩管道會有進一步體會。
>>點我看圖

64.Incident Response and Computer Forensics, Second Edition
陳彥銘 ★★★︰關於事件應變與電腦鑑識的書,觀念跟流程還沒過時,但是裡面提供的技術資訊,可能不見得符合今日所需。
>>點我看圖

65.Security Engineering
陳彥銘 ★★★★★︰關於資安工程的全面參考書。第二版比第一版多了將近一倍。作者是全球知名的資安專家,內容有條理,絕對是必備的參考書。
>>點我看圖

66.Computer-Related Risks
陳彥銘 ★★★★︰作者根據 ACM International Risks Forum 裡面的案例編輯成書,描寫因為電腦發生錯誤而導致的風險,值得一看,增廣見聞。
>>點我看圖

67.Security Data Visualization: Graphical Techniques for Network Analysis
陳彥銘 ★★★︰關於資訊安全資料視覺化的應用書本之一。內容可參考,但是離許多商業產品還有一段距離。
>>點我看圖

68.Applied Security Visualization
陳彥銘 ★★★★︰同樣關於資安視覺化的應用書本,與前書相當,作者還製作了 DAVIX工具DVD。
>>點我看圖

69.Security in Computing, 4th Edition
陳彥銘 ★★★︰本書第二版助我通過CISSP考試 (2001),之後也陸續推薦此書給需要考試的同事。
>>點我看圖

70.Security Metrics: Replacing Fear, Uncertainty, and Doubt
陳彥銘 ★★★︰關於如何衡量資訊安全的書籍。書本將觀念簡易帶出,對於實作或是案例著墨不深,但可參考作者多年的經驗與觀察。
>>點我看圖

71.The Art of War for Security Managers
陳彥銘 ★★★︰以孫子兵法為名針對安全管理者所寫的書。但是離孫子兵法的地位還差很遠。僅供參考。
>>點我看圖

72.加密與解密(第三版) 
threesecond ★★★★★︰加密與解密第三次改版了,從第一版起我每一本都有買,內容從各種軟體保護、加殼脫殼、看門狗程式等,到跟蹤/反跟蹤技術都有,相當硬底子的好書。
>>點我看圖

73.Handbook of Applied Cryptography
陳彥銘 ★★★★★︰如果想要深入了解密碼學的原理及基礎,本書為不可或缺之參考書。同時也有免費線上 PDF 版。
>>點我看圖

74.Applied Cryptography
陳彥銘 ★★★★︰Bruce Schenier 的出名著作,對密碼學的理論部分不如上一本書來得深入,但是對於密碼學的應用廣為探討,也是必備的參考書。
>>點我看圖

75.The Code Book(碼書:編碼與解碼的戰爭)
陳彥銘 ★★★︰密碼學的故事書,雖然厚,但是值得輕鬆一看。
>>點我看圖

76.Advances in Cryptology
陳彥銘 ★★★︰Crypto、Asiacrypt、Eurocrypt等知名密碼學國際會議的論文集,可以藉此書了解每個會議的新觀念與論文。
>>點我看圖

77.Privacy on the Line
陳彥銘 ★★★★︰知名密碼學家Diffie所寫的關於隱私權的書籍,是適合了解觀念與觀點的好書。
>>點我看圖

78.Writing Secure Code
陳彥銘 ★★★︰關於撰寫安全軟體的書本濫觴之一。有些觀念及微軟的經驗還是很值得參考學習,但是書的內容並不足以涵蓋今日所需。
>>點我看圖

79.The Security Development Lifecycle
陳彥銘 ★★★★︰關於微軟執行 SDL 的著名參考著作。觀念完整,但是執行的部分應該配合微軟近年來發表的一些免費工具。
>>點我看圖

80.Software Security: Building Security In
陳彥銘 ★★★︰軟體安全的濫觴之一,此書是非微軟派別的基本書。但是兩者對 SDL 的觀念,其實有許多共同之處。
>>點我看圖

81.Improving Web Application Security
陳彥銘 ★★★︰微軟關於 web app 安全的書籍。不同處在於作者群是以pattern 的角度來看web app所面臨的威脅及反制之道,因此具參考價值。
>>點我看圖

82.How to Break Software Security
陳彥銘 ★★★︰本書推薦原因是因為書薄,言簡意賅,還有附工具軟體,值得參考。
>>點我看圖

83.How to Break Web Software
陳彥銘 ★★★︰同樣也是言簡意賅,書也很薄。只是本書是針對web app的安全測試而寫。
>>點我看圖

儲存管理

84.大話儲存-網路儲存系統原理精解與最佳實踐
threesecond ★★★★︰專門探討儲存媒體的書不多,但這本絕對是佼佼者,除了硬碟、RAID原理以外,包括FTTB通訊協定、指令集、儲存媒體虛擬化,都有提到,要廣泛了解各種儲存媒體的話,不能錯過這本。
>>點我看圖

85.資料重現-檔案系統原理精解與資料恢復最佳實踐
threesecond ★★★★︰這本和上一本是同時推出的兩本重量級好書,要談檔案救援必先精通檔案系統,這本書就是在介紹各類檔案系統與RAID救援的方法,以及各種問題原因、救援前的風險,若要深入了解資料救援必讀此書。
>>點我看圖

86.硬碟博士開講
threesecond ★★★★︰這本書絕版了。這本書是曾在Seagate任職的硬碟博士寫的,雖然很舊了(1999年出版),但溫徹斯特硬碟機原理不變,這本書的觀念也就不會變,仍然是了解硬碟機詳細構造的必讀好書。
>>點我看圖

通用新知與企業管理

87.The Old New Thing
王森 ★★★★★︰由一位一直從事Windows核心開發的工程師所撰寫,講述許多Windows之所以有目前設計的緣由,豐富的逸事和秘辛,當作歷史故事別有趣味。
>>點我看圖

88.Peopleware: Productive Projects and Teams
王建興 ★★★★★︰從以人為本的角度切入,探討如何增加軟體團隊的生產能力。倘若想成為一名稱職的軟體開發團隊主管,本書相當值得你一讀。
>>點我看圖

89.創意人:創意思考的自我訓練
陳昇瑋 ★★★★★:瞭解創意的來源,訓練自己成為有創意的程式人
>>點我看圖

90.第五項修練: 學習型組織的藝術與實務
陳宏一 ★★★★★:工作是不斷解決問題的過程,而問題的根本原因常常不僅是你眼前所看到的。察覺出隱含的問題,以系統化角度的方式去思考,才能對症下藥,一勞永逸。
>>點我看圖

91.深入淺出PMP
threesecond ★★★★︰專案管理是現代人必備的基本技能,學習專案管理才能有效運用時間與各項資源,有心進展主管職的人更應該讀,是每個人都必須讀的好書,這本書以非常多淺顯易懂的圖例來說明,很好上手。>>點我看圖

92.思考的技術
陳宏一 ★★★★★︰思考需要訓練,需要系統化進行,才會客觀理性。本書將思考視為一門技術,歸納出成功的思考途徑。
>>點我看圖

93.公司絕不會告訴你的50個祕密
陳宏一 ★★★★★︰在職場上很多事情不是想像中的那麼單純,很多理所當然的觀念,卻在真實工作環境裡是行不通的。本書的很多眉角,幫助你順利存活於職場上,保有正確的工作態度,社會新鮮人更是不可不看!>>點我看圖

94.別當正常的傻瓜: 避免正常人的錯誤,成為超凡的決策者
陳宏一 ★★★★︰人是情感的動物,決策時不免常忽略理性客觀的評估,而做出錯誤的決策,本書以生活常見的案例,提醒避開思路陷阱。
>>點我看圖

95.水煮三國
陳宏一 ★★★★︰三國題材一直是企業管理奉為圭臬的重要課題,本書以輕鬆詼諧的筆觸,以各個三國人物置入實際職場角色,讓讀者從中習得管理、策略、領導、心理等技巧,讓你您會心一笑。
>>點我看圖

96.科學革命:一段不存在的歷史
王盈勛 ★★★★:2010年你不容錯過的書。這是有趣的科技史,讓我們認識到,我們視為理所當然的科學革命,並沒有那麼理所當然。
>>點我看圖

97.杜拉克-管理的使命
王盈勛 ★★★★★:只讀一本杜拉克,就讀這一本。下個月是杜拉克101歲冥誕,可以讀這本書來紀念這位不朽的大師。
>>點我看圖

98.你拿什麼定義自己?:組織大師韓第的生命故事
王盈勛 ★★★★★:深厚的歐洲人文環境才出得來的管理思想家,如果你對美式管理思維已感到厭倦,看看韓第是怎麼說的。
>>點我看圖

99.資訊經營法則
王盈勛 ★★★★★:談網路與資訊經濟最基本而扎實的著作,連Google都請作者去當總顧問,你怎能不看?
>>點我看圖

100.資訊革命了什麼?
王盈勛 ★★★★★:打破資訊樂觀主義的迷思,告訴你為何科技對我們真正的影響,往往和我們預期的不一樣。
>>點我看圖

101.NET & TEN
王盈勛 ★★★★★:老牌科技預言家的著作,十多年後回顧,大體上都是正確的,相當不簡單。
>>點我看圖

原生JavaScript技巧大收集

1、原生JavaScript實現字串長度截取

function cutstr(str, len) {

var temp;

var icount = 0;

var patrn = /[^\x00-\xff]/;

var strre = “”;

for (var i = 0; i < str.length; i++) {

if (icount < len – 1) {

temp = str.substr(i, 1);

if (patrn.exec(temp) == null) {

icount = icount + 1

} else {

icount = icount + 2

}

strre += temp

} else {

break

}

}

return strre + “…”

}

2、原生JavaScript獲取功能變數名稱主機

function getHost(url) {

var host = “null”;

if(typeof url == “undefined”|| null == url) {

url = window.location.href;

}

var regex = /^\w+\:\/\/([^\/]*).*/;

var match = url.match(regex);

if(typeof match != “undefined” && null != match) {

host = match[1];

}

return host;

}

3、原生JavaScript清除空格

String.prototype.trim = function() {

var reExtraSpace = /^\s*(.*?)\s+$/;

return this.replace(reExtraSpace, “$1”)

}

4、原生JavaScript替換全部

String.prototype.replaceAll = function(s1, s2) {

return this.replace(new RegExp(s1, “gm”), s2)

}

5、原生JavaScript轉義html標籤

function HtmlEncode(text) {

return text.replace(/&/g, ‘&’).replace(/\”/g, ‘”‘).replace(/</g, ‘<‘).replace(/>/g, ‘>’)

}

6、原生JavaScript還原html標籤

function HtmlDecode(text) {

return text.replace(/&/g, ‘&’).replace(/”/g, ‘\”‘).replace(/</g, ‘<‘).replace(/>/g, ‘>’)

}

7、原生JavaScript時間日期格式轉換

Date.prototype.Format = function(formatStr) {

var str = formatStr;

var Week = [‘日’, ‘一’, ‘二’, ‘三’, ‘四’, ‘五’, ‘六’];

str = str.replace(/yyyy|YYYY/, this.getFullYear());

str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : ‘0’ + (this.getYear() % 100));

str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : ‘0’ + (this.getMonth() + 1));

str = str.replace(/M/g, (this.getMonth() + 1));

str = str.replace(/w|W/g, Week[this.getDay()]);

str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : ‘0’ + this.getDate());

str = str.replace(/d|D/g, this.getDate());

str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : ‘0’ + this.getHours());

str = str.replace(/h|H/g, this.getHours());

str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : ‘0’ + this.getMinutes());

str = str.replace(/m/g, this.getMinutes());

str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : ‘0’ + this.getSeconds());

str = str.replace(/s|S/g, this.getSeconds());

return str

}

8、原生JavaScript判斷是否為數字類型

function isDigit(value) {

var patrn = /^[0-9]*$/;

if (patrn.exec(value) == null || value == “”) {

return false

} else {

return true

}

}

9、原生JavaScript設置cookie

function setCookie(name, value, Hours) {

var d = new Date();

var offset = 8;

var utc = d.getTime() + (d.getTimezoneOffset() * 60000);

var nd = utc + (3600000 * offset);

var exp = new Date(nd);

exp.setTime(exp.getTime() + Hours * 60 * 60 * 1000);

document.cookie = name + “=” + escape(value) + “;path=/;expires=” + exp.toGMTString() + “;domain=360doc.com;”

}

10、原生JavaScript獲取cookie

function getCookie(name) {

var arr = document.cookie.match(new RegExp(“(^| )” + name + “=([^;]*)(;|$)”));

if (arr != null) return unescape(arr[2]);

return null

}

11、原生JavaScript加入我的最愛

function AddFavorite(sURL, sTitle) {

try {

window.external.addFavorite(sURL, sTitle)

} catch(e) {

try {

window.sidebar.addPanel(sTitle, sURL, “”)

} catch(e) {

alert(“加入收藏失敗,請使用Ctrl+D進行添加”)

}

}

}

12、原生JavaScript設為首頁

function setHomepage() {

if (document.all) {

document.body.style.behavior = ‘url(#default#homepage)’;

document.body.setHomePage(‘http://www.jq-school.com’)

} else if (window.sidebar) {

if (window.netscape) {

try {

netscape.security.PrivilegeManager.enablePrivilege(“UniversalXPConnect”)

} catch(e) {

alert(“該操作被流覽器拒絕,如果想啟用該功能,請在位址欄內輸入 about:config,然後將項 signed.applets.codebase_principal_support 值該為true”)

}

}

var prefs = Components.classes[‘@mozilla.org/preferences-service;1’].getService(Components.interfaces.nsIPrefBranch);

prefs.setCharPref(‘browser.startup.homepage’, ‘http://www.jq-school.com’)

}

}

13、原生JavaScript判斷IE6

var ua = navigator.userAgent.toLowerCase();

var isIE6 = ua.indexOf(“msie 6”) > -1;

if (isIE6) {

try {

document.execCommand(“BackgroundImageCache”, false, true)

} catch(e) {}

}

14、原生JavaScript載入樣式檔

function LoadStyle(url) {

try {

document.createStyleSheet(url)

} catch(e) {

var cssLink = document.createElement(‘link’);

cssLink.rel = ‘stylesheet’;

cssLink.type = ‘text/css’;

cssLink.href = url;

var head = document.getElementsByTagName(‘head’)[0];

head.appendChild(cssLink)

}

}

15、原生JavaScript返回腳本內容

function evalscript(s) {

if(s.indexOf(‘<script’) == -1) return s;

var p = /<script[^\>]*?>([^\x00]*?)<\/script>/ig;

var arr = [];

while(arr = p.exec(s)) {

var p1 = /<script[^\>]*?src=\”([^\>]*?)\”[^\>]*?(reload=\”1\”)?(?:charset=\”([\w\-]+?)\”)?><\/script>/i;

var arr1 = [];

arr1 = p1.exec(arr[0]);

if(arr1) {

appendscript(arr1[1], ”, arr1[2], arr1[3]);

} else {

p1 = /<script(.*?)>([^\x00]+?)<\/script>/i;

arr1 = p1.exec(arr[0]);

appendscript(”, arr1[2], arr1[1].indexOf(‘reload=’) != -1);

}

}

return s;

}

16、原生JavaScript清除腳本內容

function stripscript(s) {

return s.replace(/<script.*?>.*?<\/script>/ig, ”);

}

17、原生JavaScript動態載入指令檔

function appendscript(src, text, reload, charset) {

var id = hash(src + text);

if(!reload && in_array(id, evalscripts)) return;

if(reload && $(id)) {

$(id).parentNode.removeChild($(id));

}

 

evalscripts.push(id);

var scriptNode = document.createElement(“script”);

scriptNode.type = “text/javascript”;

scriptNode.id = id;

scriptNode.charset = charset ? charset : (BROWSER.firefox ? document.characterSet : document.charset);

try {

if(src) {

scriptNode.src = src;

scriptNode.onloadDone = false;

scriptNode.onload = function () {

scriptNode.onloadDone = true;

JSLOADED[src] = 1;

};

scriptNode.onreadystatechange = function () {

if((scriptNode.readyState == ‘loaded’ || scriptNode.readyState == ‘complete’) && !scriptNode.onloadDone) {

scriptNode.onloadDone = true;

JSLOADED[src] = 1;

}

};

} else if(text){

scriptNode.text = text;

}

document.getElementsByTagName(‘head’)[0].appendChild(scriptNode);

} catch(e) {}

}

18、原生JavaScript返回按ID檢索的元素物件

function $(id) {

return !id ? null : document.getElementById(id);

}

19、原生JavaScript返回流覽器版本內容

function browserVersion(types) {

var other = 1;

for(i in types) {

var v = types<i> ? types<i> : i;

if(USERAGENT.indexOf(v) != -1) {

var re = new RegExp(v + ‘(\\/|\\s)([\\d\\.]+)’, ‘ig’);

var matches = re.exec(USERAGENT);

var ver = matches != null ? matches[2] : 0;

other = ver !== 0 && v != ‘mozilla’ ? 0 : other;

}else {

var ver = 0;

}

eval(‘BROWSER.’ + i + ‘= ver’);

}

BROWSER.other = other;

}

20、原生JavaScript元素顯示的通用方法

function $(id) {

return !id ? null : document.getElementById(id);

}

function display(id) {

var obj = $(id);

if(obj.style.visibility) {

obj.style.visibility = obj.style.visibility == ‘visible’ ? ‘hidden’ : ‘visible’;

} else {

obj.style.display = obj.style.display == ” ? ‘none’ : ”;

}

}

21、原生JavaScript中有insertBefore方法,可惜卻沒有insertAfter方法?用如下函數實現

function insertAfter(newChild,refChild){

var parElem=refChild.parentNode;

if(parElem.lastChild==refChild){

refChild.appendChild(newChild);

}else{

parElem.insertBefore(newChild,refChild.nextSibling);

}

}

22、原生JavaScript中相容流覽器綁定元素事件

function addEventSamp(obj,evt,fn){

if (obj.addEventListener) {

obj.addEventListener(evt, fn, false);

}else if(obj.attachEvent){

obj.attachEvent(‘on’+evt,fn);

}

}

23、原生JavaScript游標停在文字的後面,文字方塊獲得焦點時調用

function focusLast(){

var e = event.srcElement;

var r =e.createTextRange();

r.moveStart(‘character’,e.value.length);

r.collapse(true);

r.select();

}

24、原生JavaScript檢驗URL連結是否有效

function getUrlState(URL){

var xmlhttp = new ActiveXObject(“microsoft.xmlhttp”);

xmlhttp.Open(“GET”,URL, false);

try{

xmlhttp.Send();

}catch(e){

}finally{

var result = xmlhttp.responseText;

if(result){

if(xmlhttp.Status==200){

return(true);

}else{

return(false);

}

}else{

return(false);

}

}

}

25、原生JavaScript格式化CSS樣式代碼

function formatCss(s){//格式化代碼

s = s.replace(/\s*([\{\}\:\;\,])\s*/g, “$1”);

s = s.replace(/;\s*;/g, “;”); //清除連續分號

s = s.replace(/\,[\s\.\#\d]*{/g, “{“);

s = s.replace(/([^\s])\{([^\s])/g, “$1 {\n\t$2”);

s = s.replace(/([^\s])\}([^\n]*)/g, “$1\n}\n$2”);

s = s.replace(/([^\s]);([^\s\}])/g, “$1;\n\t$2”);

return s;

}

26、原生JavaScript壓縮CSS樣式代碼

function yasuoCss (s) {//壓縮代碼

s = s.replace(/\/\*(.|\n)*?\*\//g, “”); //刪除注釋

s = s.replace(/\s*([\{\}\:\;\,])\s*/g, “$1”);

s = s.replace(/\,[\s\.\#\d]*\{/g, “{“); //容錯處理

s = s.replace(/;\s*;/g, “;”); //清除連續分號

s = s.match(/^\s*(\S+(\s+\S+)*)\s*$/); //去掉首尾空白

return (s == null) ? “” : s[1];

}

27、原生JavaScript獲取當前路徑

var currentPageUrl = “”;

if (typeof this.href === “undefined”) {

currentPageUrl = document.location.toString().toLowerCase();

}

else {

currentPageUrl = this.href.toString().toLowerCase();

}

28、原生JavaScriptIP轉成整型

function _ip2int(ip){

var num = 0;

ip = ip.split(“.”);

num = Number(ip[0]) * 256 * 256 * 256 + Number(ip[1]) * 256 * 256 + Number(ip[2]) * 256 + Number(ip[3]);

num = num >>> 0;

return num;

}

29、原生JavaScript整型解析為IP地址

function _int2iP(num){

var str;

var tt = new Array();

tt[0] = (num >>> 24) >>> 0;

tt[1] = ((num << 8) >>> 24) >>> 0;

tt[2] = (num << 16) >>> 24;

tt[3] = (num << 24) >>> 24;

str = String(tt[0]) + “.” + String(tt[1]) + “.” + String(tt[2]) + “.” + String(tt[3]);

return str;

}

30、原生JavaScript實現checkbox全選與全不選

function checkAll() {

var selectall = document.getElementById(“selectall”);

var allbox = document.getElementsByName(“allbox”);

if (selectall.checked) {

for (var i = 0; i < allbox.length; i++) {

allbox.checked = true;

}

} else {

for (var i = 0; i < allbox.length; i++) {

allbox.checked = false;

}

}

}

31、原生JavaScript判斷是否移動設備

function isMobile(){

if (typeof this._isMobile === ‘boolean’){

return this._isMobile;

}

var screenWidth = this.getScreenWidth();

var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport;

var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperiment.toLowerCase() === “new”);

if(!fixViewPortsExperiment){

if(!this.isAppleMobileDevice()){

screenWidth = screenWidth/window.devicePixelRatio;

}

}

var isMobileScreenSize = screenWidth < 600;

var isMobileUserAgent = false;

this._isMobile = isMobileScreenSize && this.isTouchScreen();

return this._isMobile;

}

32、原生JavaScript判斷是否移動設備訪問

function isAppleMobileDevice(){

return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()));

}

33、原生JavaScript判斷是否蘋果移動設備訪問

function isAppleMobileDevice(){

return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()));

}

34、原生JavaScript判斷是否安卓移動設備訪問

function isAndroidMobileDevice(){

return (/android/i.test(navigator.userAgent.toLowerCase()));

}

35、原生JavaScript判斷是否Touch螢幕

function isTouchScreen(){

return ((‘ontouchstart’ in window) || window.DocumentTouch && document instanceof DocumentTouch);

}

36、原生JavaScript判斷是否在安卓上的穀歌流覽器

function isNewChromeOnAndroid(){

if(this.isAndroidMobileDevice()){

var userAgent = navigator.userAgent.toLowerCase();

if((/chrome/i.test(userAgent))){

var parts = userAgent.split(‘chrome/’);

var fullVersionString = parts[1].split(” “)[0];

var versionString = fullVersionString.split(‘.’)[0];

var version = parseInt(versionString);

if(version >= 27){

return true;

}

}

}

return false;

}

37、原生JavaScript判斷是否打開視窗

function isViewportOpen() {

return !!document.getElementById(‘wixMobileViewport’);

}

38、原生JavaScript獲取移動設備初始化大小

function getInitZoom(){

if(!this._initZoom){

var screenWidth = Math.min(screen.height, screen.width);

if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){

screenWidth = screenWidth/window.devicePixelRatio;

}

this._initZoom = screenWidth /document.body.offsetWidth;

}

return this._initZoom;

}

39、原生JavaScript獲取移動設備最大化大小

function getZoom(){

var screenWidth = (Math.abs(window.orientation) === 90) ? Math.max(screen.height, screen.width) : Math.min(screen.height, screen.width);

if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){

screenWidth = screenWidth/window.devicePixelRatio;

}

var FixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport;

var FixViewPortsExperimentRunning = FixViewPortsExperiment && (FixViewPortsExperiment === “New” || FixViewPortsExperiment === “new”);

if(FixViewPortsExperimentRunning){

return screenWidth / window.innerWidth;

}else{

return screenWidth / document.body.offsetWidth;

}

}

40、原生JavaScript獲取移動設備螢幕寬度

function getScreenWidth(){

var smallerSide = Math.min(screen.width, screen.height);

var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport;

var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperiment.toLowerCase() === “new”);

if(fixViewPortsExperiment){

if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){

smallerSide = smallerSide/window.devicePixelRatio;

}

}

return smallerSide;

}

41、原生 JavaScript完美判斷是否為網址

function IsURL(strUrl) {

var regular = /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i

if (regular.test(strUrl)) {

return true;

}

else {

return false;

}

}

42、原生JavaScript根據樣式名稱檢索元素物件

function getElementsByClassName(name) {

var tags = document.getElementsByTagName(‘*’) || document.all;

var els = [];

for (var i = 0; i < tags.length; i++) {

if (tags.className) {

var cs = tags.className.split(‘ ‘);

for (var j = 0; j < cs.length; j++) {

if (name == cs[j]) {

els.push(tags);

break

}

}

}

}

return els

}

43、原生JavaScript判斷是否以某個字串開頭

String.prototype.startWith = function (s) {

return this.indexOf(s) == 0

}

44、原生JavaScript判斷是否以某個字串結束

String.prototype.endWith = function (s) {

var d = this.length – s.length;

return (d >= 0 && this.lastIndexOf(s) == d)

}

45、原生JavaScript返回IE流覽器的版本號

function getIE(){

if (window.ActiveXObject){

var v = navigator.userAgent.match(/MSIE ([^;]+)/)[1];

return parseFloat(v.substring(0, v.indexOf(“.”)))

}

return false

}

46、原生JavaScript獲取頁面高度

function getPageHeight(){

var g = document, a = g.body, f = g.documentElement, d = g.compatMode == “BackCompat”

? a

: g.documentElement;

return Math.max(f.scrollHeight, a.scrollHeight, d.clientHeight);

}

47、原生JavaScript獲取頁面scrollLeft

function getPageScrollLeft(){

var a = document;

return a.documentElement.scrollLeft || a.body.scrollLeft;

}

48、原生JavaScript獲取頁面可視寬度

function getPageViewWidth(){

var d = document, a = d.compatMode == “BackCompat”

? d.body

: d.documentElement;

return a.clientWidth;

}

49、原生JavaScript獲取頁面寬度

function getPageWidth(){

var g = document, a = g.body, f = g.documentElement, d = g.compatMode == “BackCompat”

? a

: g.documentElement;

return Math.max(f.scrollWidth, a.scrollWidth, d.clientWidth);

}

50、原生JavaScript獲取頁面scrollTop

function getPageScrollTop(){

var a = document;

return a.documentElement.scrollTop || a.body.scrollTop;

}

51、原生JavaScript獲取頁面可視高度

function getPageViewHeight() {

var d = document, a = d.compatMode == “BackCompat”

? d.body

: d.documentElement;

return a.clientHeight;

}

52、原生JavaScript跨流覽器添加事件

function addEvt(oTarget,sEvtType,fnHandle){

if(!oTarget){return;}

if(oTarget.addEventListener){

oTarget.addEventListener(sEvtType,fnHandle,false);

}else if(oTarget.attachEvent){

oTarget.attachEvent(“on” + sEvtType,fnHandle);

}else{

oTarget[“on” + sEvtType] = fnHandle;

}

}

53、原生JavaScript跨流覽器刪除事件

function delEvt(oTarget,sEvtType,fnHandle){

if(!oTarget){return;}

if(oTarget.addEventListener){

oTarget.addEventListener(sEvtType,fnHandle,false);

}else if(oTarget.attachEvent){

oTarget.attachEvent(“on” + sEvtType,fnHandle);

}else{

oTarget[“on” + sEvtType] = fnHandle;

}

}

54、原生JavaScript去掉url首碼

function removeUrlPrefix(a){

a=a.replace(/:/g,”:”).replace(/./g,”.”).replace(///g,”/”);

while(trim(a).toLowerCase().indexOf(“http://”)==0){

a=trim(a.replace(/http:\/\//i,””));

}

return a;

}

55、原生JavaScript亂數時間戳記

function uniqueId(){

var a=Math.random,b=parseInt;

return Number(new Date()).toString()+b(10*a())+b(10*a())+b(10*a());

}

56、原生JavaScript全形半形轉換,iCase: 0全到半,1半到全,其他不轉化

function chgCase(sStr,iCase){

if(typeof sStr != “string” || sStr.length <= 0 || !(iCase === 0 || iCase == 1)){

return sStr;

}

var i,oRs=[],iCode;

if(iCase){/*半->全*/

for(i=0; i<sStr.length;i+=1){

iCode = sStr.charCodeAt(i);

if(iCode == 32){

iCode = 12288;

}else if(iCode < 127){

iCode += 65248;

}

oRs.push(String.fromCharCode(iCode));

}

}else{/*全->半*/

for(i=0; i<sStr.length;i+=1){

iCode = sStr.charCodeAt(i);

if(iCode == 12288){

iCode = 32;

}else if(iCode > 65280 && iCode < 65375){

iCode -= 65248;

}

oRs.push(String.fromCharCode(iCode));

}

}

return oRs.join(“”);

}

57、原生JavaScript確認是否鍵盤有效輸入值

function checkKey(iKey){

if(iKey == 32 || iKey == 229){return true;}/*空格和異常*/

if(iKey>47 && iKey < 58){return true;}/*數字*/

if(iKey>64 && iKey < 91){return true;}/*字母*/

if(iKey>95 && iKey < 108){return true;}/*數位鍵盤1*/

if(iKey>108 && iKey < 112){return true;}/*數位鍵盤2*/

if(iKey>185 && iKey < 193){return true;}/*符號1*/

if(iKey>218 && iKey < 223){return true;}/*符號2*/

return false;

}

58、原生JavaScript獲取網頁被卷去的位置

function getScrollXY() {

return document.body.scrollTop ? {

x: document.body.scrollLeft,

y: document.body.scrollTop

}: {

x: document.documentElement.scrollLeft,

y: document.documentElement.scrollTop

}

}

59、原生JavaScript另一種正則日期格式化函數+調用方法

Date.prototype.format = function(format){ //author: meizz

var o = {

“M+” : this.getMonth()+1, //month

“d+” : this.getDate(),    //day

“h+” : this.getHours(),   //hour

“m+” : this.getMinutes(), //minute

“s+” : this.getSeconds(), //second

“q+” : Math.floor((this.getMonth()+3)/3),  //quarter

“S” : this.getMilliseconds() //millisecond

}

if(/(y+)/.test(format)) format=format.replace(RegExp.$1,

(this.getFullYear()+””).substr(4 – RegExp.$1.length));

for(var k in o)if(new RegExp(“(“+ k +”)”).test(format))

format = format.replace(RegExp.$1,

RegExp.$1.length==1 ? o[k] :

(“00″+ o[k]).substr((“”+ o[k]).length));

return format;

}

alert(new Date().format(“yyyy-MM-dd hh:mm:ss”));

60、原生JavaScript時間個性化輸出功能

/*

1、< 60s, 顯示為“剛剛”

2、>= 1min && < 60 min, 顯示與當前時間差“XX分鐘前”

3、>= 60min && < 1day, 顯示與當前時間差“今天 XX:XX”

4、>= 1day && < 1year, 顯示日期“XX月XX日 XX:XX”

5、>= 1year, 顯示具體日期“XXXX年XX月XX日 XX:XX”

*/

function timeFormat(time){

var date = new Date(time)

, curDate = new Date()

, year = date.getFullYear()

, month = date.getMonth() + 1

, day = date.getDate()

, hour = date.getHours()

, minute = date.getMinutes()

, curYear = curDate.getFullYear()

, curHour = curDate.getHours()

, timeStr;

 

if(year < curYear){

timeStr = year +’年’+ month +’月’+ day +’日 ‘+ hour +’:’+ minute;

}else{

var pastTime = curDate – date

, pastH = pastTime/3600000;

 

if(pastH > curHour){

timeStr = month +’月’+ day +’日 ‘+ hour +’:’+ minute;

}else if(pastH >= 1){

timeStr = ‘今天 ‘ + hour +’:’+ minute +’分’;

}else{

var pastM = curDate.getMinutes() – minute;

if(pastM > 1){

timeStr = pastM +’分鐘前’;

}else{

timeStr = ‘剛剛’;

}

}

}

return timeStr;

}

61、原生JavaScript解決offsetX相容性問題

// 針對火狐不支持offsetX/Y

function getOffset(e){

var target = e.target, // 當前觸發的目標物件

eventCoord,

pageCoord,

offsetCoord;

 

// 計算當前觸發元素到文檔的距離

pageCoord = getPageCoord(target);

 

// 計算游標到文檔的距離

eventCoord = {

X : window.pageXOffset + e.clientX,

Y : window.pageYOffset + e.clientY

};

 

// 相減獲取游標到第一個定位的父元素的座標

offsetCoord = {

X : eventCoord.X – pageCoord.X,

Y : eventCoord.Y – pageCoord.Y

};

return offsetCoord;

}

 

function getPageCoord(element){

var coord = { X : 0, Y : 0 };

// 計算從當前觸發元素到根節點為止,

// 各級 offsetParent 元素的 offsetLeft 或 offsetTop 值之和

while (element){

coord.X += element.offsetLeft;

coord.Y += element.offsetTop;

element = element.offsetParent;

}

return coord;

}

62、原生JavaScript常用的規則運算式

//正整數

/^[0-9]*[1-9][0-9]*$/;

//負整數

/^-[0-9]*[1-9][0-9]*$/;

//正浮點數

/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/;

//負浮點數

/^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/;

//浮點數

/^(-?\d+)(\.\d+)?$/;

//email地址

/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;

//url地址

/^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$/;

//年/月/日(年-月-日、年.月.日)

/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/;

//匹配中文字元

/[\u4e00-\u9fa5]/;

//匹配帳號是否合法(字母開頭,允許5-10位元組,允許字母數位底線)

/^[a-zA-Z][a-zA-Z0-9_]{4,9}$/;

//匹配空白行的規則運算式

/\n\s*\r/;

//匹配中國郵遞區號

/[1-9]\d{5}(?!\d)/;

//匹配身份證

/\d{15}|\d{18}/;

//匹配國內電話號碼

/(\d{3}-|\d{4}-)?(\d{8}|\d{7})?/;

//匹配IP地址

/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/;

//匹配首尾空白字元的規則運算式

/^\s*|\s*$/;

//匹配HTML標記的規則運算式

< (\S*?)[^>]*>.*?|< .*? />;

63、原生JavaScript實現返回頂部的通用方法

function backTop(btnId) {

var btn = document.getElementById(btnId);

var d = document.documentElement;

var b = document.body;

window.onscroll = set;

btn.style.display = “none”;

btn.onclick = function() {

btn.style.display = “none”;

window.onscroll = null;

this.timer = setInterval(function() {

d.scrollTop -= Math.ceil((d.scrollTop + b.scrollTop) * 0.1);

b.scrollTop -= Math.ceil((d.scrollTop + b.scrollTop) * 0.1);

if ((d.scrollTop + b.scrollTop) == 0) clearInterval(btn.timer, window.onscroll = set);

},

10);

};

function set() {

btn.style.display = (d.scrollTop + b.scrollTop > 100) ? ‘block’: “none”

}

};

backTop(‘goTop’);

64、原生JavaScript獲得URLGET參數值

// 用法:如果地址是 test.htm?t1=1&t2=2&t3=3, 那麼能取得:GET[“t1”], GET[“t2”], GET[“t3”]

function get_get(){

querystr = window.location.href.split(“?”)

if(querystr[1]){

GETs = querystr[1].split(“&”)

GET =new Array()

for(i=0;i<GETs.length;i++){

tmp_arr = GETs.split(“=”)

key=tmp_arr[0]

GET[key] = tmp_arr[1]

}

}

return querystr[1];

}

65、原生JavaScript實現全選通用方法

function checkall(form, prefix, checkall) {

var checkall = checkall ? checkall : ‘chkall’;

for(var i = 0; i < form.elements.length; i++) {

var e = form.elements;

if(e.type==”checkbox”){

e.checked = form.elements[checkall].checked;

}

}

}

66、原生JavaScript實現全部取消選擇通用方法

function uncheckAll(form) {

for (var i=0;i<form.elements.length;i++){

var e = form.elements;

if (e.name != ‘chkall’)

e.checked=!e.checked;

}

}

67、原生JavaScript實現打開一個表單通用方法

function openWindow(url,windowName,width,height){

var x = parseInt(screen.width / 2.0) – (width / 2.0);

var y = parseInt(screen.height / 2.0) – (height / 2.0);

var isMSIE= (navigator.appName == “Microsoft Internet Explorer”);

if (isMSIE) {

var p = “resizable=1,location=no,scrollbars=no,width=”;

p = p+width;

p = p+”,height=”;

p = p+height;

p = p+”,left=”;

p = p+x;

p = p+”,top=”;

p = p+y;

retval = window.open(url, windowName, p);

} else {

var win = window.open(url, “ZyiisPopup”, “top=” + y + “,left=” + x + “,scrollbars=” + scrollbars + “,dialog=yes,modal=yes,width=” + width + “,height=” + height + “,resizable=no” );

eval(“try { win.resizeTo(width, height); } catch(e) { }”);

win.focus();

}

}

68、原生JavaScript判斷是否為用戶端設備

function client(o){

var b = navigator.userAgent.toLowerCase();

var t = false;

if (o == ‘isOP’){

t = b.indexOf(‘opera’) > -1;

}

if (o == ‘isIE’){

t = b.indexOf(‘msie’) > -1;

}

if (o == ‘isFF’){

t = b.indexOf(‘firefox’) > -1;

}

return t;

}

69、原生JavaScript獲取選項按鈕的值

function get_radio_value(field){

if(field&&field.length){

for(var i=0;i<field.length;i++){

if(field.checked){

return field.value;

}

}

}else {

return ;

}

}

70、原生JavaScript獲取核取方塊的值

function get_checkbox_value(field){

if(field&&field.length){

for(var i=0;i<field.length;i++){

if(field.checked && !field.disabled){

return field.value;

}

}

}else {

return;

}

}

71、原生JavaScript判斷是否為郵箱

function isEmail(str){

var re=/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;

if (re.test(str) != true) {

return false;

}else{

return true;

}

}

72、原生JavaScript判斷是否有清單中的危險字元

function isValidReg(chars){

var re=/<|>|\[|\]|\{|\}|『|』|※|○|●|◎|§|△|▲|☆|★|◇|◆|□|▼|㊣|﹋|⊕|⊙|〒|ㄅ|ㄆ|ㄇ|ㄈ|ㄉ|ㄊ|ㄋ|ㄌ|ㄍ|ㄎ|ㄏ|ㄐ|ㄑ|ㄒ|ㄓ|ㄔ|ㄕ|ㄖ|ㄗ|ㄘ|ㄙ|ㄚ|ㄛ|ㄜ|ㄝ|ㄞ|ㄟ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄧ|ㄨ|ㄩ|■|▄|▆|\*|@|#|\^|\\/;

if (re.test( chars) == true) {

return false;

}else{

return true;

}

}

73、原生JavaScript判斷字串是否大於規定的長度

function isValidLength(chars, len) {

if (chars.length < len) {

return false;

}

return true;

}

74、原生JavaScript判斷字串是為網址不區分大小寫

function isValidURL( chars ) {

var re=/^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(\S+\.\S+)$/;

if (!isNULL(chars)) {

chars = jsTrim(chars);

if (chars.match(re) == null)

return false;

else

return true;

}

return false;

}

75、原生JavaScript判斷字串是否為小數

function isValidDecimal( chars ) {

var re=/^\d*\.?\d{1,2}$/;

if (chars.match(re) == null)

return false;

else

return true;

}

76、原生JavaScript判斷字串是否為整數

function isNumber( chars ) {

var re=/^\d*$/;

if (chars.match(re) == null)

return false;

else

return true;

}

77、原生JavaScript判斷字串是否為浮點數

function isFloat( str ) {

for(i=0;i<str.length;i++)  {

if ((str.charAt(i)<“0″ || str.charAt(i)>”9”)&& str.charAt(i) != ‘.’){

return false;

}

}

return true;

}

78、原生JavaScript判斷字元是否為A-Za-z英文字母

function isLetters( str ){

var re=/^[A-Za-z]+$/;

if (str.match(re) == null)

return false;

else

return true;

}

79、原生JavaScript判斷字串是否郵遞區號

function isValidPost( chars ) {

var re=/^\d{6}$/;

if (chars.match(re) == null)

return false;

else

return true;

}

80、原生JavaScript判斷字元是否空NULL

function isNULL( chars ) {

if (chars == null)

return true;

if (jsTrim(chars).length==0)

return true;

return false;

}

81、原生JavaScript用規則運算式提取頁面代碼中所有網址

var aa = document.documentElement.outerHTML.match(/(url\(|src=|href=)[\”\’]*([^\”\’\(\)\<\>\[\] ]+)[\”\’\)]*|(http:\/\/[\w\-\.]+[^\”\’\(\)\<\>\[\] ]+)/ig).join(“\r\n”).replace(/^(src=|href=|url\()[\”\’]*|[\”\’\>\) ]*$/igm,””);

alert(aa)

82、原生JavaScript用規則運算式清除相同的陣列(低效率)

Array.prototype.unique=function(){

return this.reverse().join(“,”).match(/([^,]+)(?!.*\1)/ig).reverse();

};

83、原生JavaScript用規則運算式清除相同的陣列(高效率)

String.prototype.unique=function(){

var x=this.split(/[\r\n]+/);

var y=”;

for(var i=0;i<x.length;i++){

if(!new RegExp(“^”+x.replace(/([^\w])/ig,”\\$1″)+”[        DISCUZ_CODE_2        ]quot;,”igm”).test(y)){

y+=x+”\r\n”

}

}

return y

};

84、原生JavaScript用規則運算式按字母排序,對每行進行陣列排序

function SetSort(){

var text=K1.value.split(/[\r\n]/).sort().join(“\r\n”);//順序

var test=K1.value.split(/[\r\n]/).sort().reverse().join(“\r\n”);//反序

K1.value=K1.value!=text?text:test;

}

85、原生JavaScript字串反序

function IsReverse(text){

return text.split(”).reverse().join(”);

}

86、原生JavaScript用規則運算式清除html代碼中的腳本

function clear_script(){

K1.value=K1.value.replace(/<script.*?>[\s\S]*?<\/script>|\s+on[a-zA-Z]{3,16}\s?=\s?”[\s\S]*?”|\s+on[a-zA-Z]{3,16}\s?=\s?'[\s\S]*?’|\s+on[a-zA-Z]{3,16}\s?=[^ >]+/ig,””);

}

87、原生JavaScript動態執行JavaScript腳本

function javascript(){

try{

eval(K1.value);

}catch(e){

alert(e.message);

}

}

88、原生JavaScript動態執行VBScript腳本

function vbscript(){

try{

var script=document.getElementById(“K1″).value;

if(script.trim()==””)return;

window.execScript(‘On Error Resume Next \n’+script+’\n If Err.Number<>0 Then \n MsgBox “請輸入正確的VBScript腳本!”,48,”腳本錯誤!” \n End If’,”vbscript”)

}catch(e){

alert(e.message);

}

}

89、原生JavaScript實現金額大寫轉換函數

function transform(tranvalue) {

try {

var i = 1;

var dw2 = new Array(“”, “萬”, “億”); //大單位

var dw1 = new Array(“拾”, “佰”, “仟”); //小單位

var dw = new Array(“零”, “壹”, “貳”, “三”, “肆”, “伍”, “陸”, “柒”, “捌”, “玖”); //整數部分用

//以下是小寫轉換成大寫顯示在合計大寫的文字方塊中

//分離整數與小數

var source = splits(tranvalue);

var num = source[0];

var dig = source[1];

//轉換整數部分

var k1 = 0; //計小單位

var k2 = 0; //計大單位

var sum = 0;

var str = “”;

var len = source[0].length; //整數的長度

for (i = 1; i <= len; i++) {

var n = source[0].charAt(len – i); //取得某個位元數上的數字

var bn = 0;

if (len – i – 1 >= 0) {

bn = source[0].charAt(len – i – 1); //取得某個位元數前一位元上的數字

}

sum = sum + Number(n);

if (sum != 0) {

str = dw[Number(n)].concat(str); //取得該數位對應的大寫數位,並插入到str字串的前面

if (n == ‘0’) sum = 0;

}

if (len – i – 1 >= 0) { //在數字範圍內

if (k1 != 3) { //加小單位

if (bn != 0) {

str = dw1[k1].concat(str);

}

k1++;

} else { //不加小單位,加大單位

k1 = 0;

var temp = str.charAt(0);

if (temp == “萬” || temp == “億”) //若大單位前沒有數位則舍去大單位

str = str.substr(1, str.length – 1);

str = dw2[k2].concat(str);

sum = 0;

}

}

if (k1 == 3) //小單位到千則大單位進一

{

k2++;

}

}

//轉換小數部分

var strdig = “”;

if (dig != “”) {

var n = dig.charAt(0);

if (n != 0) {

strdig += dw[Number(n)] + “角”; //加數字

}

var n = dig.charAt(1);

if (n != 0) {

strdig += dw[Number(n)] + “分”; //加數字

}

}

str += “元” + strdig;

} catch(e) {

return “0元”;

}

return str;

}

//拆分整數與小數

function splits(tranvalue) {

var value = new Array(”, ”);

temp = tranvalue.split(“.”);

for (var i = 0; i < temp.length; i++) {

value = temp;

}

return value;

}

90、原生JavaScript常用的規則運算式大收集

匹配中文字元的規則運算式: [\u4e00-\u9fa5]

匹配雙位元組字元(包括漢字在內):[^\x00-\xff]

匹配空行的規則運算式:\n[\s| ]*\r

匹配 HTML 標記的規則運算式:<(.*)>.*<\/\1>|<(.*) \/>

匹配首尾空格的規則運算式:(^\s*)|(\s*$)

匹配 IP 地址的規則運算式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g

匹配 Email 地址的規則運算式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

匹配網址 URL 的規則運算式:http://(/[\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

sql 語句:^(select|drop|delete|create|update|insert).*[        DISCUZ_CODE_39        ]nbsp;

非負整數:^\d+[        DISCUZ_CODE_39        ]nbsp;

正整數:^[0-9]*[1-9][0-9]*[        DISCUZ_CODE_39        ]nbsp;

非正整數:^((-\d+)|(0+))[        DISCUZ_CODE_39        ]nbsp;

負整數:^-[0-9]*[1-9][0-9]*[        DISCUZ_CODE_39        ]nbsp;

整數:^-?\d+[        DISCUZ_CODE_39        ]nbsp;

非負浮點數:^\d+(\.\d+)?[        DISCUZ_CODE_39        ]nbsp;

正浮點數:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))[        DISCUZ_CODE_39        ]nbsp;

非正浮點數:^((-\d+\.\d+)?)|(0+(\.0+)?))[        DISCUZ_CODE_39        ]nbsp;

英文字串:^[A-Za-z]+[        DISCUZ_CODE_39        ]nbsp;

英文大寫串:^[A-Z]+[        DISCUZ_CODE_39        ]nbsp;

英文小寫串:^[a-z]+[        DISCUZ_CODE_39        ]nbsp;

英文字元數位串:^[A-Za-z0-9]+[        DISCUZ_CODE_39        ]nbsp;

英數字加底線串:^\w+[        DISCUZ_CODE_39        ]nbsp;

E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+[        DISCUZ_CODE_39        ]nbsp;

URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$ 或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\’:+!]*([^<>\”\”])*[        DISCUZ_CODE_39        ]nbsp;

郵遞區號:^[1-9]\d{5}[        DISCUZ_CODE_39        ]nbsp;

電話號碼:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?[        DISCUZ_CODE_39        ]nbsp;

手機號碼:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}[        DISCUZ_CODE_39        ]nbsp;

雙位元組字元(包括漢字在內):^\x00-\xff

匹配首尾空格:(^\s*)|(\s*$)

匹配 HTML 標記:<(.*)>.*<\/\1>|<(.*) \/>

匹配空行:\n[\s| ]*\r

提取資訊中的網路連結:(h|H)(r|R)(e|E)(f|F) *= *(‘|”)?(\w|\\|\/|\.)+(‘|”| *|>)?

提取資訊中的郵寄地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

提取資訊中的圖片連結:(s|S)(r|R)(c|C) *= *(‘|”)?(\w|\\|\/|\.)+(‘|”| *|>)?

提取資訊中的 IP 位址:(\d+)\.(\d+)\.(\d+)\.(\d+)

提取資訊中的中國手機號碼:(86)*0*13\d{9}

提取資訊中的中國固定電話號碼:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}

提取資訊中的中國電話號碼(包括移動和固定電話):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}

提取資訊中的中國郵遞區號:[1-9]{1}(\d+){5}

提取資訊中的浮點數(即小數):(-?\d*)\.?\d+

提取資訊中的任何數位 :(-?\d*)(\.\d+)?

IP:(\d+)\.(\d+)\.(\d+)\.(\d+)

電話區號:^0\d{2,3}$

騰訊 QQ 號:^[1-9]*[1-9][0-9]*[        DISCUZ_CODE_39        ]nbsp;

帳號(字母開頭,允許 5-16 位元組,允許字母數位底線):^[a-zA-Z][a-zA-Z0-9_]{4,15}[        DISCUZ_CODE_39        ]nbsp;

中文、英文、數位及底線:^[\u4e00-\u9fa5_a-zA-Z0-9]+$

91、原生JavaScript實現表單改變事件resize的操作(相容所以的流覽器)

(function(){

var fn = function(){

var w = document.documentElement ? document.documentElement.clientWidth : document.body.clientWidth

,r = 1255

,b = Element.extend(document.body)

,classname = b.className;

if(w < r){

//當表單的寬度小於1255的時候執行相應的操作

}else{

//當表單的寬度大於1255的時候執行相應的操作

}

}

if(window.addEventListener){

window.addEventListener(‘resize’, function(){ fn(); });

}else if(window.attachEvent){

window.attachEvent(‘onresize’, function(){ fn(); });

}

fn();

})();

92、原生JavaScript用正則清除空格分左右

function ltrim(s){ return s.replace( /^(\s*| *)/, “”); }

function rtrim(s){ return s.replace( /(\s*| *)$/, “”); }

function trim(s){ return ltrim(rtrim(s));}

93、原生JavaScript判斷變數是否空值

/**

* 判斷變數是否空值

* undefined, null, ”, false, 0, [], {} 均返回true,否則返回false

*/

function empty(v){

switch (typeof v){

case ‘undefined’ : return true;

case ‘string’    : if(trim(v).length == 0) return true; break;

case ‘boolean’   : if(!v) return true; break;

case ‘number’    : if(0 === v) return true; break;

case ‘object’    :

if(null === v) return true;

if(undefined !== v.length && v.length==0) return true;

for(var k in v){return false;} return true;

break;

}

return false;

}

94、原生JavaScript實現base64解碼

function base64_decode(data){

var b64 = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”;

var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,ac = 0,dec = “”,tmp_arr = [];

if (!data) { return data; }

data += ”;

do {

h1 = b64.indexOf(data.charAt(i++));

h2 = b64.indexOf(data.charAt(i++));

h3 = b64.indexOf(data.charAt(i++));

h4 = b64.indexOf(data.charAt(i++));

bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

o1 = bits >> 16 & 0xff;

o2 = bits >> 8 & 0xff;

o3 = bits & 0xff;

if (h3 == 64) {

tmp_arr[ac++] = String.fromCharCode(o1);

} else if (h4 == 64) {

tmp_arr[ac++] = String.fromCharCode(o1, o2);

} else {

tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);

}

} while (i < data.length);

dec = tmp_arr.join(”);

dec = utf8_decode(dec);

return dec;

}

95、原生JavaScript實現utf8解碼

function utf8_decode(str_data){

var tmp_arr = [],i = 0,ac = 0,c1 = 0,c2 = 0,c3 = 0;str_data += ”;

while (i < str_data.length) {

c1 = str_data.charCodeAt(i);

if (c1 < 128) {

tmp_arr[ac++] = String.fromCharCode(c1);

i++;

} else if (c1 > 191 && c1 < 224) {

c2 = str_data.charCodeAt(i + 1);

tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));

i += 2;

} else {

c2 = str_data.charCodeAt(i + 1);

c3 = str_data.charCodeAt(i + 2);

tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));

i += 3;

}

}

return tmp_arr.join(”);

}

96、原生JavaScript獲取表單可見範圍的寬與高

function getViewSize(){

var de=document.documentElement;

var db=document.body;

var viewW=de.clientWidth==0 ?  db.clientWidth : de.clientWidth;

var viewH=de.clientHeight==0 ?  db.clientHeight : de.clientHeight;

return Array(viewW ,viewH);

}

96、原生JavaScript判斷IE版本號(既簡潔、又向後相容!)

var _IE = (function(){

var v = 3, div = document.createElement(‘div’), all = div.getElementsByTagName(‘i’);

while (

div.innerHTML = ‘<!–[if gt IE ‘ + (++v) + ‘]><i></i><![endif]–>’,

all[0]

);

return v > 4 ? v : false ;

}());

97、原生JavaScript獲取流覽器版本號

function browserVersion(types) {

var other = 1;

for (i in types) {

var v = types ? types : i;

if (USERAGENT.indexOf(v) != -1) {

var re = new RegExp(v + ‘(\\/|\\s|: )([\\d\\.]+)’, ‘ig’);

var matches = re.exec(USERAGENT);

var ver = matches != null ? matches[2] : 0;

other = ver !== 0 && v != ‘mozilla’ ? 0 : other;

} else {

var ver = 0;

}

eval(‘BROWSER.’ + i + ‘= ver’);

}

BROWSER.other = other;

}

98、原生JavaScript判斷滑鼠是否移出事件

function isMouseOut(e, handler) {

if (e.type !== ‘mouseout’) {

return false;

}

var reltg = e.relatedTarget ? e.relatedTarget : e.type === ‘mouseout’ ? e.toElement : e.fromElement;

while (reltg && reltg !== handler) {

reltg = reltg.parentNode;

}

return (reltg !== handler);

}

99、原生JavaScript半形轉換為全形函數

function ToDBC(str){

var result = ”;

for(var i=0; i < str.length; i++){

code = str.charCodeAt(i);

if(code >= 33 && code <= 126){

result += String.fromCharCode(str.charCodeAt(i) + 65248);

}else if (code == 32){

result += String.fromCharCode(str.charCodeAt(i) + 12288 – 32);

}else{

result += str.charAt(i);

}

}

return result;

}

100、原生JavaScript全形轉換為半形函數

function ToCDB(str){

var result = ”;

for(var i=0; i < str.length; i++){

code = str.charCodeAt(i);

if(code >= 65281 && code <= 65374){

result += String.fromCharCode(str.charCodeAt(i) – 65248);

}else if (code == 12288){

result += String.fromCharCode(str.charCodeAt(i) – 12288 + 32);

}else{

result += str.charAt(i);

}

}

return result;

}

 

24個2012最受歡迎的jquery插件

—————————————————————————————————

Last month, many great jQuery plugins were created and new versions were released too. Now, lets go through some of the most popular plugins in February 2012.

1. turn.js

Adds a beautiful transition similar to real pages in a book or magazine for HTML5.

2. jQuery Scroll Path

It’s a plugin for defining custom scroll paths. It uses canvas flavored syntax to draw lines and arcs.

3. 3D Gallery

An experimental 3D gallery that uses CSS 3D transforms.

4. Anystretch

Allows you to add a dynamically-resized background image to any page or block level element.
The image will stretch to fit the page/element, and will automatically resize as the window size changes.

5. noty

It makes it easy to create alert, success, error and confirmation messages as an alternative the standard alert dialog.
Each notification is added to a queue. The notifications can be positioned at the top, topCenter (like GMail), bottom, centre, top left or top right.
There are lots of other options in the API to customize the text, animation, speed, buttons and much more.

6. Page Scroller

A powerful JavaScript based smooth scrolling navigation system that utilizes the robust jQuery library. Created entirely with ease of use in mind, the plugin will work on any website.

7. Sequence.js

Sequence is the jQuery slider plugin with infinite style. It provides the complete functionality for a website slider without forcing you to use a set theme.
In fact, Sequence has no in-built theme, leaving you complete creative control to build a unique slider using only CSS3.

8. Curtain.js

This plugin allows you to create a web page with multiple fixed panels that unroll with an amusing effect. Exactly like a curtain rises.

9. Glisse.js

jQuery plugin for creating a fully customizable photo viewer with beautiful CSS3 transition.

10. jQuery Shadow

A plugin to create drop shadows of various types.

11. fullscreen.js

This jQuery plugin lets you create full screen galleries where the slides are shown on the entire screen using the full screen APIs provided by Firefox 10+ and Chrome 15+ (and possibly Safari 5.1+).
In all other browsers it falls back to displaying the slideshow in the entire view port.

12. jPages

jPages is a client-side pagination plugin but it gives you a lot more features comparing to most of the other plugins for this purpose, such as auto page turn, key and scroll browse, showing items with delay, completely customizable navigation panel and also integration with Animate.css and Lazy Load.

13. jurlp

jQuery plugin for parsing, manipulating, filtering and monitoring URLs in “href” and “src” attributes within arbitrary elements (including document.location.href), as well as creating anchor elements from URLs found in HTML/text.

14. Metro JS

jQuery plugin developed to easily enable Metro interfaces on the web. This release focuses on Live Tiles, the Application Bar and Theming. It’s early in the development phase, but all features should work on at least IE7+(Win/WinPhone), Firefox, Chrome, Android, Opera, and Safari(OSX/iOS).

15. DataTables v1.9

A highly flexible tool, based upon the foundations of progressive enhancement, which will add advanced interaction controls to any HTML table

16. SimpleVid

SimpleVid is a free and easy way to host and embed your own fluid videos. It uses flash to for browsers that don’t support h.264, so you can encode once as a baseline h.264 mp4 and play anywhere.

17. blur.js

jQuery plugin that produces psuedo-transparent blurred elements over other elements.

18. Twitter Friends Widget v2.0

There is a Facebook like box, Google+ badge, what about a Twitter fan box?!

19. Bacon

Bacon is a jQuery plugin that allows you to wrap text around a bezier curve or a line.

20. Responsive Google Maps

When scrolling a website on your mobile device you can get trapped in a Google map due to the Maps scrollbar of death™. This plugin gives you a native Google maps on your website and a safe fallback to the static image API of Google maps for smaller devices.

21. ProQuo

ProQuo is a quick way to encourage your readers to spread your content through twitter. Simply define the regions in your markup that you would like to make “tweetable” and ProQuo will handle the rest.

22. Lazy Load v1.7

Lazy Load is a jQuery plugin to delay loading of images in long web pages. Images outside of viewport (visible part of web page) won’t be loaded before user scrolls to them.

23. Flippy

Flippy is a cross-browser flip effect plugin which allows you to flip whatever html element you want.

24. jQuery Geo v1.0a4

jQuery Geo, an open-source geospatial mapping project from Applied Geographics, provides a streamlined API for a large percentage of your online mapping needs. Whether you just want to display a map on a web page as quickly as possible or you are a more advanced GIS user, jQuery Geo can help!

Enjoyed this roundup? check Popular jQuery Plugins of January 2012.

MySQL 資料庫儲存引擎

 

這篇文章主要討論 Memory, MyISAM, InnoDB 三種儲存引擎

項目 MyISAM InnoDB Memory
空間限制 64TB 記憶體
transaction x x
大量 Insert 速度
設置外來鍵 x x
鎖定層級 資料表 資料列 資料表
二元樹索引 不知
雜湊索引 x
全文搜尋索引 x x
資料壓縮 x x
資料快取 x
索引快取
記憶體佔用
磁碟佔用 x

對於 MyISAM 來說,最大的好處是成本低,而且可以 create views ,這是其他儲存引擎辦不到的,但缺點就是鎖定層級以 table 為單位,而且不支援 transaction ,這些地方輸給 InnoDB 。不過 InnoDB 也是有缺點像是不支援 FULLTEXT 的索引,且記憶體佔用多、磁碟空間耗用大…等等。

我找到一篇文章針對 MyISAM, InnoDB 和 Falcon 來做比較,在這裡面 MyISAM和 InnoDB 表現都沒有差很多,唯獨在測 READ_PK_RANGE 和 READ_KEY_POINT 時候, MyISAM 爛掉了(不過主角其實是 Falcon 因為它被打趴了)。原因是:There MyISAM shows bad scalability with increasing count of thread. I think the reason is pread system call MyISAM uses to access data and retrieving from OS cache is not scaled.
InnoDB vs MyISAM vs Falcon benchmarks – part 1

而 Memory 儲存引擎的最大優點就是快、快、很快、不會對硬碟頻繁讀寫、並且用 HASH 雜湊索引(但不曉得有沒有 Btree 二元樹索引)!另外它有個特性,就是會在硬碟建立一個 .frm 檔,目的是為了存資料表的 scheme ,但是每一筆 record 還是儲存在記憶體中,這也意味著如果斷電或是關機,資料就會消失不見。

實際應用:

假設我有兩個不同類型的 Table ,分別儲存 App Data 和 Session ,我有大量連線,從伺服器上的紀錄看來,開機半天左右,總共處理近九百萬個連線(這是實際數據)。

系統開機至現在共進行 8,944,853 次查詢
總共 每小時 每分 每秒
8,945 k 806.51 k 12.73 k 224.19

而 App Data 的資料表作用和 Session 資料表個作用分別如下:

每個 App 啟動時,都會有一個 Session ID,而每筆 Session 都被當成一筆 Record Insert 到 Table 中做紀錄,當 Session 起始/結束的時候,才把更新的資料寫到 App Data 中。

對於 Session 個資料表的處理,我採用 Memory 為儲存引擎,因為 Session 掉了並不可惜,但卻可以換來極佳的效率,而 App Data 的資料表,我則是採用 InnoDB ,雖然相較於 MyISAM 會花上更多的 Cost 而且效率較差,但是他提供很好的鎖定(以row為單位)以及安全的復原機制,另外也支援外來鍵的設定。

推薦閱讀文章:
MySQL Storage Engine Architecture, Part 3: Details and Comparison
13.4. The MEMORY (HEAP) Storage Engine
MySQL Storage Engines

[問題排除]WORD文件結束後, 出現視窗, (MICROSOFT OFFICE WORLD 發生問題, 必需關閉, 謹此致歉), 回復工作後, 出現新的WORD文件, 要再關閉後才會結束.

連結

 

問題

WORD文件結束後, 出現視窗, (MICROSOFT OFFICE WORLD 發生問題, 必需關閉, 謹此致歉), 回復工作後, 出現新的WORD文件, 要再關閉後才會結束.

 

回答

跟 Normal.dot 範本有關

請到以下路徑,將 Normal.dot 檔案先更名,然後再開啟 Word 看看

C:\Documents and Settings\您的使用者名稱\Application Data\Microsoft\Templates

 

假如還是有問題,請參考

每次結束 Word 時,都會出現提示詢問您是否要將變更儲存至 Normal.dot 共用範本

http://support.microsoft.com/kb/291352/zh-tw

 

GRUB for DOS 0.4.3中文手冊

來源

GRUB for DOS 0.4.3

一、免費下載:
http://grub4dos.sourceforge.net/
http://grub4dos.freespaces.com/
http://download.gna.org/grub4dos/
http://sarovar.org/projects/grub4dos/
http://grub4dos.jot.com/

二、教學:
http://grub4dos.sourceforge.net/wiki/index.php/Grub4dos_tutorial
http://grub4dos.sourceforge.net/wiki/

三、其他連結(含論壇):
http://sarovar.org/projects/grub4dos
http://freshmeat.net/projects/grub4dos/
http://marc.herbert.free.fr/linux/win2linstall.html
http://www.cn-dos.net/forum/forumdisplay.php?fid=11(United DOS Forum ,DOS聯盟論壇啟動盤室)
http://www.znpc.net/bbs/forumdisplay.php?fid=4(SYSOFT時空論壇,中文)

四、Other Resources(其他資源):
Ralf Brown’s Interrupt List: It’s cool.
http://www.ctyme.com/rbrown.htm
A Disk Editor View of the NTFS Boot Sector and “Bootstrap Code” http://www.therdcom.com/asm/mbr/NTFSbrHexEd.htm
The Second Extended File System(Internal Layout)
http://www.nongnu.org/ext2-doc/ext2.html
OSD: PC bootstrap
http://my.execpc.com/CE/AC/geezer/osd/boot/
eXtended Memory Specification:
http://freedos.sourceforge.net/freedos/news/press/1991-xms30.html
High-res high-speed VESA tutorial
http://www.monstersoft.com/tutorial1/
BIOS Data Area
http://www.bioscentral.com/misc/bda.htm
Hardware and Software Documentation
http://www.o3one.org/hwdocs.html

五、簡介:
GRUB for DOS(一般簡寫為GRUB4DOS)是GNU GRUB的DOS編譯版本(準確的說,GRUB4DOS是一個基於GNU GRUB Legacy的二次開發版本),它可以運行於真實模式的DOS環境下,而且它還具有很多新功能,例如:它可以通過Windows(NT)的boot.ini((使用grldr檔)、Linux的kexec(使用grub.exe檔)、lilo來啟動。另外,相對於GNU GRUB來說,它的虛擬磁碟功能是另一個重大改進,通過BIOS使用這個內建功能,可以從軟碟或者硬碟映射檔中啟動傳統的DOS/Windows9x系統。

六、特色:
1.GNU GRUB主要是突破boot loader原先512 bytes限制,利用3 stages方法擴大成多重開機及彈性開機,把GRUB安裝到硬碟MBR的傳統方法是:先運行root (xxx,x),然後setup (xxx)——前面一句是指定一個分區partition,該分區須存放有/boot/stage1和/boot/stage2文件,後面的setup (xxx) 是將引導代碼寫入指定磁片的MBR。這樣安裝的GRUB,其MBR引導代碼被設置為從固定的分區載入stage2,一旦該分區出了問題,系統便無法引導;如果我們想刪除該分區,或格式化分區,或者做一些會引起該分區序號改變的操作,就需要預先重新安裝一次grub,重新指定存放stage檔的分區,否則也會引導失敗。這一點上grub顯得不夠靈活。

而GRUB4DOS採取了新的策略:其MBR引導代碼並非固定地指向某個分區,而是搜索所有分區的 root 目錄,查找並載入grldr,只要某分區上存有一份grldr,就能啟動。而且安裝時可以將原微軟的MBR備份,啟動時如果找不到grldr,便自動載入備份的MBR。顯然這種方式更加靈活、穩健,所以GRUB4DOS雖然保留了GNU GRUB的全部命令和功能,包括setup命令,但不推薦使用傳統的安裝方式。而且它的引導代碼雖然可以搜索硬碟,但識別檔系統的能力有限,目前僅限於FAT12/FAT16/FAT32/NTFS/EXT2/EXT3這幾種,所以可能需要專門設一個分區來存放grldr。

2.GNU GRUB主要是為啟動Linux系統設計,但同時可借用Windows的boot manager來啟動Windows系統。而GRUB for DOS則兩邊都可以。一種使用grub.exe檔,可以從Linux或DOS文字介面執行,另一種使用grldr檔,可以從MBR/partition boot sector或Windows NT/2000/XP/2003/Vista boot manager進行啟動,也可以當作bootable CDROM的eltorito boot file。

3.GRUB for DOS改良加強GNU GRUB的MAP指令,可以透過image files用來創造虛擬硬碟或軟碟,甚至DOS開啟後,這些虛擬設備仍可存取。

4.圖片背景支援:相信大多數用戶都樂於使用圖片背景來代替單調的黑白畫面。雖然僅能支持 640×480@14位色,但也總比兩色好得多。

5.簡體中文支援:GRUB4DOS中同時發佈有支持簡體中文的grldr和grub.exe,大大方便了中文用戶。

6.光碟機支援:該功能使得用戶可以再GRUB環境下訪問光碟機,並可由光碟機啟動,很實用。

七、安裝方式:

1.Install to MBR

把GRUB4DOS啟動代碼安裝到MBR後,開機後便能直接進入GRUB4DOS。

以下使用bootlace.com(可以運行於DOS/Linux、Windows 95/98/Me、虛擬硬碟)
(1)MBR of first hard drive under DOS, Windows 95/98/Me
bootlace 0x80
(2)MBR of IDE channel 0, primary drive under Linux
bootlace /dev/hda
(3)MBR of hard drive image file aa.dsk
bootlace aa.dsk

以下使用 grubinst.exe(可以運行於FreeBSD/Linux、Windows NT/2000/XP/2003/Vista、虛擬硬碟)
(4)MBR of first hard drive under Windows NT family OSs(Windows NT/2000/XP/2003/Vista)
grubinst (hd0)
(5)MBR of IDE channel 0, primary drive under Linux/FreeBSD
grubinst “(hd0)”
或是用Device Name如下:
grubinst /dev/hda (Linux)
grubinst /dev/ad0 (FreeBSD)
(6)MBR of hard drive image file aa.dsk
grubinst aa.dsk
注意:grubinst有圖形介面grubinst_gui,利用它可以更簡單地把啟動代碼安裝到MBR/啟動磁區裏。

安裝啟動代碼到MBR後,還需要把grldr和menu.lst拷貝到硬碟上任意一個FAT16/FAT32/NTFS/EXT2分區的根目錄裏。
———————————
本方案的優點:
•不依賴於作業系統
•能夠自動搜索硬碟上各個分區的grldr檔
———————————–

2.Install to partition boot sector

GRUB4DOS的啟動代碼也可以安裝到某一FAT16/FAT32/NTFS/EXT2分區的啟動磁區中。當從該分區啟動時,會引導GRUB4DOS。

(1)first primary partition of the first hard drive
grubinst (hd0,0)
or
grubinst –install-partition=0 (hd0)
or
grubinst -p=0 (hd0)
(2)first primary partition of the hard drive image file aa.dsk
grubinst –install-partition=0 aa.dsk
or
grubinst -p=0 aa.dsk

安裝啟動代碼到啟動磁區後,還需要把grldr和menu.lst拷貝到該分區的根目錄裏。

本方案的優點:
•不依賴於作業系統
•不需要修改MBR,因而可以使GRUB4DOS和其他的啟動管理器共存

—————————————————————————————–
下面的這些啟動方式都不會改變硬碟的主引導記錄(MBR)或者分區的引導磁區。

3.Starting from DOS

(1)在DOS/Windows9x的CONFIG.SYS中使用下列方式:

install=c:\some\where\grub.exe –config-file=FILE

(2)在DOS命令行中直接執行GRUB.EXE。

grub.exe –config-file=FILE

如果沒有使用–config-file選項,缺省的功能表檔是 (hd0,0)/menu.lst。
FILE可以功能表檔的名字,也可以是功能表的內容。例如:

grub.exe –config-file=”root (hd0,0);chainloader +1″

在DOS下啟動GRUB4DOS後,可以用quit命令返回到DOS中。

4.Booting via the Windows NT/2000/XP/2003 boot manager

在Windows NT系列作業系統(NT/2000/XP/2003)的c:\boot.ini(此為隱藏檔)最後面增加下面一項:

c:\grldr=”Start GRUB4DOS”

如果boot.ini中的timeout值為零,把它設置為大於0的數位,例如timeout=30,然後將boot.ini存檔。把grldr和menu.lst拷貝到C:\。
下一次啟動Windows時,你會發現啟動畫面中多了Start GRUB4DOS這一選項,使用它便可啟動GRUB4DOS。
注意:boot.ini檔一般是隱藏的,你需要在資料夾選項中設置顯示所有檔,或者在cmd中使用以下命令來去掉boot.ini的隱藏屬性:

attrib -s -r -h c:\boot.ini

5.Booting via the Windows Vista boot manager

首先,把grldr.mbr拷貝到C:\下,然後在cmd中使用如下面四個指令:

bcdedit /create /d “GRUB4DOS” /application bootsector
bcdedit /set {id} device boot
bcdedit /set {id} path \grldr.mbr
bcdedit /displayorder {id} /addlast

其中第二、三、以及四個指令不是真的要輸入 {id},在第一個指令輸入之後,電腦會輸出一個類似 {xxxx-xxxx-xxxx-xxxx} 的 ID,請你把這個 {xxxx-xxxx-xxxx-xxxx} 帶入第二、三、以及四個指令內。

然後把grldr和menu.lst拷貝到任意一個FAT16/FAT32/NTFS/EXT2分區的根目錄。
該方案也可應用於Windows NT/2000/XP/2003,但這些系統中修改啟動功能表不是使用bcdedit,而是通過在boot.ini的最後加上這樣的一行:

c:\grldr.mbr=”Start GRUB4DOS”

下一次啟動Windows時,你會發現啟動畫面中多了Start GRUB4DOS這一選項,使用它便可啟動GRUB4DOS。
該方案的優點:
—————————————
•不需要修改MBR和啟動磁區
•能夠自動搜索硬碟上各個分區的grldr檔
—————————————

6.Starting from Linux

首先使用kexec patch指令更新你的Linux kernel。
其次鍵入下列指令:

kexec -l grub.exe
kexec -e

7.Loading GRUB for DOS using other boot loader

在下列boot loader中,grub.exe可以當作linux kernel使用。
(1)syslinux
可以在syslinux.cfg中寫入下列段落:
label GRUB4DOS
KERNEL grub.exe
(2)Grub或是另一個GRUB for DOS
可以在menu.lst中寫入下列段落:
title Load GRUB4DOS
kernel /grub.exe(或是kernel (DEVICE)/PATH/grub.exe,例如:kernel (hd0,4)/boot/grub/grub.exe)

八、Windows開機選項(menu.lst)寫法:
在GRUB for DOS的menu.lst中,一般寫法
1.DOS, Windows 95/98/Me: (MSDOS 7+)
title DOS, Windows 95/98/Me
root (hd0,0)
chainloader (hd0,0)/io.sys

2.Windows NT/2000/XP/2003:
title Windows NT/2000/XP/2003
root (hd0,0)
chainloader (hd0,0)/ntldr

3.Windows Vista:
title Windows Vista bootmgr
root (hd0,0)
chainloader (hd0,0)/bootmgr

4.啟動Windows NT的恢復控制臺的CMLDR:
title CMLDR of Windows NT/2K/XP
root (DEVICE)
chainloader (DEVICE)/cmldr

(一)配置檔menu.lst的基本結構

GRUB4DOS的配置檔和GRUB一樣,都是menu.lst。以下是一個例子:

default 0

title Boot First Partition
root (hd0,0)
chainloader +1

title Boot Second Partition
root (hd0,1)
chainloader +1

菜單項是由title來指定,該例子中有兩個title,就是說GRUB4DOS器啟動時會顯示兩個功能表項,功能表的標題是title的參數,也就是 Boot First Partition 和 Boot Second Partition。在第一個title前的命令是全局命令,它們在顯示功能表之前執行。
menu.lst一般放在和啟動檔GRLDR同樣的目錄裏。
以下是該配置檔在啟動時的畫面:
BootScreen1.jpg 
高亮的功能表項是當前選擇的功能表,用上下方向鍵可以在不同功能表中切換。如果按下回車鍵,便會以當前功能表中的命令來啟動系統。
在功能表介面按下c鍵,會進入命令行介面:
BootScreen2.jpg 
在命令行介面下,你可以手動輸入各個命令。在命令行介面下,按鍵便可以回到功能表介面。

(二)基本命令

以下是一些最為常用的命令

1.help
用來顯示其他命令的用法,例子:
help root

2.default
指定缺省的菜單項,由0開始算起,例子: default 0 該命令必須在第一個title之前指定

3.timeout
缺省的等待時間,如果在指定的時間(以秒為單位)不按任何鍵,則會啟動缺省的功能表項,例子: timeout 10 該命令必須在第一個title之前指定

4.root
用來指定根設備,例子: root (hd0,0)

5.rootnoverify
該命令也可以用來指定根設備。root在設置根設備前,先測試一下該分區的檔系統是否可以識別,而rootnoverify則省略這一測試。 rootnoverify (hd0,0)

6.chainloader
把啟動磁區的內容裝入記憶體,參數+1指的是把分區的第一個磁區,例子: chainloader +1

7.boot
啟動作業系統。在使用該命令前,必須用kernel或者chainloader把系統內核或者啟動磁區/啟動檔裝入記憶體。例子: boot
在配置檔中不需要使用這個命令。這是因為GRUB在執行了功能表項的所有命令後,會自動加上boot。該命令一般在命令行介面裏使用。

(三)設備名字

在GRUB中,硬碟設備用以下的方法來命名:
(hdm)
m是硬碟的序號。序號0相對於BIOS的第一隻硬碟。
硬碟上的分區用以下的方法來命名:
(hdm,n)
n是硬碟m裏分區的序號。主分區最多有4個,其序號為0-3,擴展分區的序號從4開始。例子:
硬碟0上的第一個主分區: (hd0,0)
硬碟1上的第一個擴展分區: (hd1,4)
設備也可以用相應的BIOS設備號來表示。例如,第一隻硬碟設備的設備號是0x80,因此,以下的表示是等價的: (hd0,0), (0x80,0), (128,0)。
另外,對於一些檔系統來說,例如FreeBSD中使用的ffs,或者是Solaris中使用的ufs,在分區中還繼續劃分為子分區。子分區的表示是在分區表示的基礎上加上從a開始計算的子分區序號。例如:
硬碟0上的第一個主分區裏的第一個子分區: (hd0,0,a)
軟碟設備用以下的方法來命名:
(fdm)
m是軟碟的序號。序號0相對於BIOS的第一隻軟碟。
軟碟設備後面同樣可以加上分區或者子分區的序號。
GRUB還有其他一些設備,比如說(cd)是光碟設備,(nd)是網路設備,等等。不過它們在特定的情形下才可以使用。

(四)檔案名字

GRUB的檔案名字是在設備名字的基礎上加上檔的路徑,例子:硬碟0上第一個主分區根目錄裏的aa.img文件: (hd0,0)/aa.img
軟碟0上boot目錄裏的aa.img文件: (fd0)/boot/aa.img
注意:目錄的分隔符號是 / ,而不是Windows/DOS下常用的 \ 。
另外,你還可以用磁區的位移和數量來指定資料,比如:
(hd0,0)0+100,200+1,300+300
表示硬碟0上第一個主分區裏,從磁區0起的100個磁區,然後是從磁區200起的1個磁區,最後是從磁區300起的300個磁區。當位移為零時,可以省略不寫,因此,
(hd0,0)+1
表示的是硬碟0上第一個主分區裏從磁區0起的1個磁區,也就是分區的第一個磁區。
GRUB中紀錄了一個根設備,它由root命令來指定,例如:
root (hd0,0)
根設備上的檔可以省略設備名,例如,使用了以上的root命令後,檔案名 +1 就等同於 (hd0,0)+1。
注意:在GRUB4DOS的擴展中,map命令中使用的檔案名的意義和以上所說的有所不同。在map命令裏,(hd0,0)+1表示的不是硬碟0上第一個主分區的第一個磁區,而是整個分區。

(五)啟動作業系統

1.啟動一般系統

一般來說,作業系統會在其所在分區的第一個磁區裏放入啟動代碼。因此,用以下的一組命令一般可以啟動硬碟0第一主分區上的作業系統:
rootnoverify (hd0,0)
chainloader +1
boot
對於不同的分區,只要修改設備名(hd0,0)就可以了。
注意:大部分的作業系統需要在第一隻硬碟的主分區裏才能正常啟動。
注意:當把該組命令作為menu.lst裏某一功能表項的內容時,最後的命令boot可以省略。
注意:該方法是通用的,它可以用來啟動以下提到的系統,只要分區的第一個磁區中存在啟動代碼。

2.啟動DOS/Windows 95/98/Me

在GRUB4DOS中,chainloader命令可以裝載DOS/Windows 95/98/Me中的io.sys。因此,可以使用類似於以下的一組命令來啟動這些系統:
rootnoverify (hd0,0)
chainloader (hd0,0)/io.sys
boot

3.啟動Windows NT/2000/XP/2003/Vista

在GRUB4DOS中,chainloader命令也可以裝載Windows NT/2000/XP/2003中的ntldr和Windows Vista中的bootmanager。因此,可以使用類似於以下的一組命令來啟動這些系統:

啟動Windows NT/2000/XP/2003:
rootnoverify (hd0,0)
chainloader (hd0,0)/ntldr
boot

啟動Windows Vista:
rootnoverify (hd0,0)
chainloader (hd0,0)/bootmanager
boot

4.啟動Linux

可以用kernel指令裝載Linux內核:

rootnoverify (hd0,0)
kernel (hd0,0)/vmlinuz
boot

在內核(hd0,0)/vmlinuz後可以加上啟動的參數。
當啟動Linux內核時,可以使initrd指令來裝載初始的內存檔。
rootnoverify (hd0,0)
kernel (hd0,0)/vmlinuz
initrd (hd0,0)/initrd
boot
注意:chainloader用於裝載啟動磁區和特定的啟動檔如io.sys和ntldr,而kernel用於裝載Linux內核和符合其標準的啟動檔。在一組啟動命令中,兩者不能同時使用。

(六)修改介面的顏色

GRUB介面的顏色可以用color指令來指定。color中指定了兩組顏色,第一組是正常文本的顏色,第二組是加亮文本(當前選擇的功能表項)的顏色。對應於每組顏色,又需要指定兩種顏色。第一種是前景的顏色,第二種是背景的顏色。因此,在color總共需要指定四種顏色,分別是,正常文本前景,正常文本背景,加亮文本前景和加亮文本背景。
顏色代碼:
black (黑色) red (紅色) green (綠色) brown (棕色) blue (藍色) magenta (紫色) cyan (青色) light-gray (灰色)
———————————————-
dark-gray (暗灰) light-red (亮紅) light-green (亮綠) yellow (黃色) light-blue (亮藍) light-magenta (亮紫) light-cyan (亮青) white (白色)
前景色可以使用全部16種顏色,而背景色只能使用前面8種顏色。
例子:
color cyan/blue white/magenta
正常文本前景: cyan (青色) 正常文本背景: blue (藍色) 加亮文本前景: white (白色) 加亮文本背景: magenta (紫色)
以上例子的顏色在運行時的畫面:
BootScreen3.jpg 

你也可以在顏色矩陣中直觀看到各前景/背景顏色搭配的效果。

black/black black/red black/green black/brown black/blue black/magenta black/cyan black/light-gray
red/black red/red red/green red/brown red/blue red/magenta red/cyan red/light-gray
green/black green/red green/green green/brown green/blue green/magenta green/cyan green/light-gray
brown/black brown/red brown/green brown/brown brown/blue brown/magenta brown/cyan brown/light-gray
blue/black blue/red blue/green blue/brown blue/blue blue/magenta blue/cyan blue/light-gray
magenta/black magenta/red magenta/green magenta/brown magenta/blue magenta/magenta magenta/cyan magenta/light-gray
cyan/black cyan/red cyan/green cyan/brown cyan/blue cyan/magenta cyan/cyan cyan/light-gray
light-gray/black light-gray/red light-gray/green light-gray/brown light-gray/blue light-gray/magenta light-gray/cyan light-gray/light-gray
dark-gray/black dark-gray/red dark-gray/green dark-gray/brown dark-gray/blue dark-gray/magenta dark-gray/cyan dark-gray/light-gray
light-red/black light-red/red light-red/green light-red/brown light-red/blue light-red/magenta light-red/cyan light-red/light-gray
black/light-green light-green/red light-green/green light-green/brown light-green/blue light-green/magenta light-green/cyan light-green/light-gray
yellow/black yellow/red yellow/green yellow/brown yellow/blue yellow/magenta yellow/cyan yellow/light-gray
light-blue/black light-blue/red light-blue/green light-blue/brown light-blue/blue light-blue/magenta light-blue/cyan light-blue/light-gray
light-magenta/black light-magenta/red light-magenta/green light-magenta/brown light-magenta/blue light-magenta/magenta light-magenta/cyan light-magenta/light-gray
light-cyan/black light-cyan/red light-cyan/green light-cyan/brown light-cyan/blue light-cyan/magenta light-cyan/cyan light-cyan/light-gray
white/black white/red white/green white/brown white/blue white/magenta white/cyan white/light-gray

color命令一般是作為全局命令,在第一個title前使用。

(七)使用背景圖片
可以用splashimage命令來載入背景圖片:

spashimage (hd0,0)/spash.gz

圖片必須是640×480,14色的XPM格式,可以用gzip來進行壓縮。
使用了該命令後,GRUB啟動時將進入圖形模式。這時,color命令指定的文本顏色將會無效。圖形模式下顏色的設置應該使用foreground命令:

foreground ffff00

以上命令設置字體的顏色。顏色用RGB值來表示,ffff00是黃色。
如果沒有使用foreground命令,缺省的文本顏色是白色。
以上兩個命令在啟動時的效果:
BootScreen4.jpg 
該例子中使用的背景圖片可以在這裡下載。
常用顏色的RGB值對應表:

000000 c0c0c0 800000 ff0000
000080 0000ff 800080 ff00ff
008000 00ff00 808000 ffff00
008080 00ffff 808080 ffffff

splashimage和foreground命令一般在第一個title前使用。

(八)使用中文介面
首先,你必須使用支持中文的版本。並且,要正常顯示中文的功能表,你需要使用fontfile命令來裝載中文字體:

fontfile (hd0,0)/fonts.gz

fonts.gz是字體檔,並且使用了gzip來壓縮。例子中使用的fonts.gz可以在這裡 下載。
fontfile命令可以和splashimage,foreground一起使用。例如:

splashimage (hd0,0)/splash.gz
foreground ffff00
fontfile (hd0,0)/fonts.gz

title 啟動第一個分區
root (hd0,0)
chainloader +1
title 啟動第二個分區
root (hd0,1)
chainloader +1
該功能表的顯示的效果為:
BootScreen5.jpg 

九、預設開機選項:
=============================================
find and load NTLDR of Windows NT/2K/XP
find and load CMLDR of Windows NT/2K/XP
find and load IO.SYS of Windows 9x/Me
find and boot Mandriva with menu.lst already installed
find and boot Linux with menu.lst already installed
commandline
floppy (fd0)
back to dos
reboot
halt
==============================================

對應的menu.lst文件(注:取自grub4dos 0.4.3下載包):

# This is a sample menu.lst file. You should make some changes to it.
# The old install method of booting via the stage-files has been removed.
# Please install GRLDR boot strap code to MBR with the bootlace.com
# utility under DOS/Win9x or Linux.

color black/cyan yellow/cyan
timeout 30
default /default

title find and load NTLDR of Windows NT/2K/XP
fallback 1
find –set-root /ntldr
chainloader /ntldr
savedefault –wait=2

title find and load CMLDR of Windows NT/2K/XP
fallback 2
find –set-root /cmldr
chainloader /cmldr
savedefault –wait=2

title find and load IO.SYS of Windows 9x/Me
fallback 3
find –set-root /io.sys
chainloader /io.sys
savedefault –wait=2

title find and boot Mandriva with menu.lst already installed
fallback 4
find –set-root /etc/mandriva-release
savedefault –wait=2
configfile /boot/grub/menu.lst

title find and boot Linux with menu.lst already installed
fallback 5
find –set-root /sbin/init
savedefault –wait=2
configfile /boot/grub/menu.lst

title commandline
savedefault –wait=2
commandline

title floppy (fd0)
chainloader (fd0)+1
rootnoverify (fd0)
savedefault –wait=2

title back to dos
savedefault –wait=2
quit

title reboot
savedefault –wait=2
reboot

title halt
savedefault –wait=2
halt

title memdrive duplicated from floppy image file (hd0,0)/sbm.bin
map –mem (hd0,0)/sbm.bin (fd0)
map –hook
chainloader (fd0)+1
rootnoverify (fd0)
savedefault –wait=2

title memdrive based on win98 partition (hd0,6)
map –mem (hd0,6)+1 (hd0)
# map –mem (hd0,0)/win98.gz (hd0)
map –hook
chainloader (hd0)+1
rootnoverify (hd0)
savedefault –wait=2

十、虛擬硬碟

map命令在GRUB Legacy中是用作磁碟交換。
比如說,你有兩隻硬碟,但兩隻硬碟上均有可啟動的系統。在第一隻硬碟上啟動時,不需要特殊的處理,直接用chainloader裝載啟動磁區就可以了。不過,如果要從第二隻硬碟上啟動,那麼單單用chainloader是不夠的,這是因為很多作業系統都預設從第一隻硬碟上裝載啟動所需的檔,如果檔不在其上,系統便不能順利地讀取,從而導致啟動失敗。
一個原始的解決方法是在BIOS中修改啟動順序,把需要啟動的硬碟放到最前面。那麼,重啟電腦後該硬碟便會成為第一隻硬碟,從而可以正常啟動。
GRUB中的map命令便是為了解決這個問題而設計的,它可以在運行時交換磁片,而無需修改BIOS。例如:

title Boot First Partition on Second Disk
map (hd0) (hd1)
map (hd1) (hd0)
chainloader (hd1,0)+1
boot

在該例子中,使用了map命令實現了(hd0)和(hd1)的交換。要注意的是,交換是在命令boot後才生效的。因此在chainloader命令中,讀取的仍然是第二隻硬碟。

1.直接映射法Direct mapping(建立虛擬磁碟)

在GRUB4DOS中,大大地擴展了map命令的用法。利用該命令可以建立虛擬磁片,例子:
把(hd0,0)根目錄下的aa.dsk檔映射為第二隻硬碟,並且使用原來硬碟上的系統啟動:

title Create Virtual Disk
map (hd0,0)/aa.dsk (hd1)
root (hd0,0)
chainloader +1
boot

把(hd0,0)根目錄下的aa.dsk檔映射為第一隻硬碟,原來的第一隻映射為第二隻硬碟,並且從aa.dsk裏虛擬出來的磁片中啟動:

title Boot From Virtual Disk
map (hd0,0)/aa.dsk (hd0)
map (hd0) (hd1)
map –hook
root (hd0,0)
chainloader +1
boot

在上面提到,map命令的映射不是馬上起作用的。但是,要從虛擬磁片中啟動,就必須從中讀取資料,因此需要使映射提前起效。在以上的例子中,map –hook的作用便是使前面map命令指定的映射立刻生效。

把(hd0,0)根目錄下的aa.img檔映射為第一隻虛擬軟碟,並從中啟動:

title Boot From Virtual Floppy
map (hd0,0)/aa.img (fd0)
map –hook
root (fd0)
chainloader +1
boot

使用這種方式進行映射後,虛擬磁片的內容和影像檔的內容是同步的,也就是說,如果你修改了虛擬磁片的內容,影像檔也同樣被更新。如果你重啟了機器,該修改的效果仍然存在。
在使用這種方式進行映射時,影像檔在磁片上的存放必須是連續的。
GRUB4DOS中建立的虛擬磁片,包括以下所說的間接映射法(採用記憶體檔),都是通過截取INT 13來實現的。因此在啟動了作業系統後,如果該系統是通過INT 13來訪問磁片的,例如各類的DOS,那麼在進入系統後仍然可以訪問虛擬碟。如果系統是採用其他方式來訪問磁片,例如Linux,各類Unix和Windows NT系列的作業系統,那麼在進入系統後便不能訪問虛擬碟。Windows 9X系列的作業系統比較特殊,它通常是使用保護模式的驅動來訪問磁片,但當它找不到合適的驅動時,會依舊使用INT 13來訪問磁片,因此,在Windows 9X下也可以訪問虛擬磁片。

『備註』:
A.虛擬光碟尚未建置。
B.在直接映射法direct mapping中映像檔image file必須是連續的。

2.間接映射法Indirect mapping(建立虛擬記憶體磁碟)

用map也可以建立虛擬記憶體磁碟,其用法和類似直接映射法direct mapping, 你只需要在map建立虛擬碟的命令中加上–mem參數就行了。例如:

把(hd0,0)根目錄下的aa.dsk檔映射為第一隻硬碟,原來的第一隻映射為第二隻硬碟,並且從aa.dsk裏虛擬出來的磁片中啟動:

title Boot From Virtual Disk
map –mem (hd0,0)/aa.dsk (hd0)
map (hd0) (hd1)
map –hook
root (hd0,0)
chainloader +1
boot

把(hd0,0)根目錄下的aa.img檔映射為第一隻虛擬軟碟,並從中啟動:

title Boot From Virtual Floppy
map –mem (hd0,0)/aa.img (fd0)
map –hook
root (fd0)
chainloader +1
boot

在間接映射法indirect mapping, 映像檔image file的內容是裝載到記憶體後才進行映射,因此映像檔image file不必是連續的,但是你必須有足夠的記憶體memory來存放映像檔image file和啟動系統。
而且,虛擬磁碟和映像檔是分離的,對虛擬磁碟所作的修改不會被更新到映像檔中。

3.Auto MBR creation(自動產生MBR)
影像檔有兩種類型。一種是檔案系統影像,它裏面只包含某一個檔案系統的資料。另一種是磁片影像,它裏面包含了類似於物理硬碟的結構,也就是,影像以MBR開始,然後才是檔案系統的資料。對於虛擬記憶體硬碟,其結構是類似於真實硬碟的,因此在使用map命令進行映射時,應該使用磁片影像。
因此在創造虛擬硬碟時, 需要一個由MBR(包含了類似於物理硬碟的結構)及partition data(檔案系統的資料)組成的映像檔image file來組合成一個實際的硬碟. 如果映像檔image file只包括partition data時, 即需加入MBR以產生完整的硬碟映像檔. GRUB for DOS在mapping硬碟映像檔時, 會測試MBR是否存在, 如不存在,則他會自動使用partition data創造MBR.例如:

title Boot from hard disk image
map –mem (hd0,0)/aa.dsk (hd0)
map (hd0) (hd1)
map –hook
chainloader (hd0,0)+1
rootnoverify (hd0,0)

aa.dsk可以是硬碟映像檔disk image或分區映像檔partition image,後者GRUB for DOS會自己產生MBR.

自動生成MBR還有一個應用,就是直接從硬碟上的裝載分區,從而生成虛擬磁片。例如:
title Load Partition From Disk
map –mem (hd0,0)+1 (hd0)
map (hd0) (hd1)
map –hook
root (hd0,0)
chainloader +1
boot
該功能表的功能是把硬碟上第一個分區的內容裝載到記憶體,並且自動在其前面加上MBR而生成虛擬磁片。然後,把該虛擬磁片映射為第一隻硬碟,原來的硬碟映射為第二隻硬碟。最後,從虛擬磁片中啟動。
在使用該功能表啟動後,系統分區的內容和好像和原來一樣,但這時實際是使用在記憶體裏的虛擬磁片。對分區的修改在重啟機器後便會消失。
該功能表是把整個分區的內容裝載到記憶體,要確定記憶體足夠大,否則命令不會成功。
在map命令中,(hd0,0)+1是指整個(hd0,0)分區,而不是(hd0,0)的第一個磁區。這種表示只是在map命令中適用,在其他的地方,(hd0,0)+1 還是原來的意義。

4.memdisk

syslinux的外部工具memdisk,利用它也可以生成虛擬記憶體磁碟(間接映射法indirect mapping)。這可以由下列兩個範例來比較:

title Boot from virtual disk using internal map command
map –mem (hd0,0)/aa.dsk (hd0)
map (hd0) (hd1)
map –hook
root (hd0,0)
chainloader +1
boot

title Boot from virtual disk using external memdisk
kernel (hd0,0)/memdisk
initrd (hd0,0)/aa.dsk
boot

該命令把aa.dsk裝入記憶體生成虛擬記憶體盤,該虛擬碟作為第一隻硬碟,原來硬碟的序號向後移動。最後,從虛擬碟中啟動。這一系列的操作都是在memdisk內完成的,GRUB的任務只是把aa.dsk裝入記憶體,然後把裝載的位址傳遞給memdisk。

如果只有一隻硬碟,那麼以上的操作可以用以下的命令完成:

title Create virtual disk using map
map –mem (hd0,0)/aa.dsk (hd0)
map (hd0) (hd1)
map –hook
root (hd0,0)
chainloader +1
boot

map和memdisk的區別:
•map是GRUB4DOS內置的功能,而memdisk是一個外部的程式
•map可以直接映射磁片上的檔,而memdisk必須要把檔裝載到記憶體裏。
•map可以把影像檔映射為第二隻硬碟,而而memdisk只能映射為第一隻硬碟。
•map有自動生成MBR的功能,而memdisk沒有。因此memdisk只能使用磁片影像,不能使用檔系統影像。

memdisk功能不支援直接映射法direct mapping或auto MBR creation.

5.虛擬設備(md)

在GRUB4DOS中,你可以用設備(md)來訪問整個記憶體,就和用(nd)訪問網路設備,用(cd)來訪問光碟類似。
GRUB4DOS也擴展了cat命令,它可以用–hex來以十六進位輸出,也可以用–locate=STRING來在檔中搜索字串。
例子:
cat –hex (hd0)+1 以十六進位形式顯示第一隻硬碟的MBR。
cat –hex (hd0,0)+1 以十六進位形式顯示第一隻硬碟第一個分區的啟動磁區
cat –hex (md)+2 以十六進位形式顯示記憶體開始1K的內容,這裏其實是中斷向量表。
cat –hex (md)0x800+1 以十六進位形式顯示記憶體從0x800 * 512 = 1M 開始512位元組的內容,也就是從擴展記憶體開始的512位元組。

6.虛擬設備(rd)

用虛擬設備(md)可以訪問從位址0開始的實體記憶體,而使用(rd)則可以訪問從某一位址開始的記憶體。
map –rd-base=ADDR 用來設置(rd)記憶體設備的開始位址(以位元組為單位)。
map –rd-size=SIZE 用來設置(rd)記憶體設備的長度(以位元組為單位)。
當把grub.exe作為linux內核啟動時,可以用指定初始盤。進入grub後,(rd)設備的開始位址和長度自動設置為初始盤的位址和長度。因此,可以在grub中用(rd)設備來訪問初始盤。
map –ram-drive=RD
用來設定訪問(rd)記憶體設備的BIOS設備名。缺省值是0x7F,表示(rd)對應的虛擬碟是軟碟設備。如果(rd)對應的虛擬碟是硬碟設備,那麼需要設置RD, 使得 0x80< RD < 0xFF。

7.map的其他參數

•–status
用於顯示當前的磁片映射。 map –status

•–floppies=M, –harddrives=N
指定軟碟/硬碟的數目。 map –harddrvies=2 使用該命令後,本地硬碟的數目設為2。

•–memdisk-raw=RAW
RAW取值0或1(預設是1)。RAW=0時,使用int15/ah=87h讀擴展記憶體。RAW=1時,使用內部的函數來讀擴展記憶體。 map –memdisk-raw=0

•–safe-mbr-hook=SMH ,–int13-scheme=SCH
這兩個參數是為了在Windows 9X下能正常使用虛擬碟而設的。
SMH取值0或1(預設是1),當你在Windows 9X下使用虛擬碟時出現問題時,可以試試使用以下的命令: map –safe-mbr-hook=0
SCH取值也是0或1(預設是1),當你在Windows 9X下使用虛擬碟時出現問題時,也可以試試使用以下的命令: map –int13-scheme=0

•–read-only
使用了該參數後,當前進行映射的磁片被設為唯讀模式。 map –mem –read-only (hd0,0)/aa.dsk (hd1)

•–fake-write
使用了該參數後,當前進行映射的磁片看似可寫,但寫入的內容均被丟棄。 map –mem –fake-write (hd0,0)/aa.dsk (hd1)

•–heads=H, –sectors-per-track=S
一般來說,map命令可以正確地計算出影像檔中使用的磁片參數。如果你想手動設置,那麼可以使用這兩個選項。 map –mem –heads=63 –sectors-per-track=255 (hd0,0)/aa.dsk (hd1)

十一、光碟機相關主題
—————————
範例:
title 從第一顆光碟啟動
cdrom –init
map –hook
chainloader (cd0)
boot
——————————
1.使用ATAPI CDROM啟動

cdrom –init ‘初始化ATAPI CDROM
map –hook ‘使ATATPI CDROM立即生效啟用,執行這個指令後,就可以用(cd0), (cd1)等代號來存取CDROM
chainloader (cd0) ‘從第一顆光碟啟動
boot

2.停用CDROM

map –unhook ‘移除(cd0), (cd1)等設備代號映射 device mapping消除map –hook效果
cdrom –stop ‘停止光碟機

『備註』:
A.如果你由光碟啟動GRUB for DOS,GRUB中支援的光碟機設備代號是(cd),它代表用可啟動光碟啟動GRUB時,用於啟動的光碟機設備。該開機光碟機雖然可直接使用,但假如你想從其他光碟機存取檔案,你還是需要使用cdrom –init、map –hook指令進行初始化。
B.在初始化光碟機後,可以用blocklist的方式來訪問其內容:
cat –hex (cd0)16+2 光碟機中使用的磁區大小是2048。
另外,iso9660檔系統驅動程式支援Rock-Ridge擴展,但不支援Joliet擴展,在讀取Joliet擴展的光碟是可能會出現問題。
C.用以下的命令可以指定搜索的埠:

cdrom –add-io-ports=0x03F601F0

以下是預設的搜索埠:0x03F601F0, 0x03760170, 0x02F600F0, 0x03860180, 0x6F006B00, 0x77007300。

3.製作開機光碟

在GRUB中,可以利用 stage2_eltorito 來製作啟動光碟:

mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso iso

stage2_eltorito和menu.lst應該放在光碟的/boot/grub目錄裏。

在GRUB for DOS可以用grldr製作開機光碟bootable CDROM的ISO檔: (下列二指令任選其一,但grldr和menu.lst要放光碟映像檔根目錄)

mkisofs -R -b grldr -no-emul-boot -boot-load-seg 0x1000 -o bootable.iso iso_root
mkisofs -R -b grldr -no-emul-boot -boot-load-size 4 -o grldr.iso iso_root

第一種方法告訴 BIOS,希望它能夠裝入整個 GRLDR 檔到記憶體。裝入記憶體後,BIOS 還應該正確設置堆疊,使得不至於把堆疊設置到 GRLDR 的程式體內,造成衝突。一般情況下,BIOS 做到這一點很容易,因為它可以設置堆疊指標為裝入的起始位址。但也不排除存在 BUGGY BIOS 的可能性。
有些 BIOS 不完全符合可啟動的 CDROM 規範,比如 VirtualPC 的就是的。這類 BIOS 只是裝入了一部分 GRLDR 磁區到記憶體,典型的可能只裝入了一個磁區(2048 位元組的大磁區)到記憶體。不過我們的代碼已經替這些 BUGGY BIOS 打了補丁。只要這些 BIOS 能夠設置正確的堆疊,不至於和裝入記憶體中的 GRLDR 磁區資料產生衝突就 OK 了。
也就是說,上述第一種製作光碟的方法,應該沒有多大問題了。這種方法很有可能適應於所有的 BIOS。

第二種方法本身就只要求 BIOS 裝入一個 CDROM 磁區到記憶體(等同於 4 個 512 位元組的小磁區)。這種方法是最保守的,沒有理由會失敗了。微軟的 win2000 啟動光碟就是這麼做的,isolinux 和 stage2_eltorito 也都是這麼做的。如果這種方法失敗了,那麼 win2000,isolinux 和 stage2_eltorito 應該都會失敗的。
對於第二種方法,我們不需要 -boot-info-table 這個參數。但是允許你用這個參數(用了和沒用是一樣的,我們的引導代碼將忽略由這個參數所傳遞的資料結構)。
對於第一種方法也一樣,不需要 -boot-info-table 這個參數,同時也是允許你用這個參數(用了和沒用是一樣的,我們的引導代碼將忽略由這個參數所傳遞的資料結構)。

4.腳本支持
GRUB4DOS中有實現了簡單的腳本支持。目前實現了 && 和 || 兩種操作:
command1 && command2 只有當 command1 的返回值是真時,command2 才被執行
command1 || command2 只有當 command1 的返回值是假時,command2 才被執行
目前不支援操作符的嵌入使用。
例子:
is64bit && default 0 is64bit || default 1
如果is64bit命令返回值是真,那麼預設的功能表項是0,否則,預設的菜單項是1。

[轉]安裝多重作業系統常見問答集

來源

安裝多重作業系統常見問答集

想要幫自己的電腦安裝數個作業系統,上網搜尋相關資料,依照資料一步驟一步驟的操作。雖然成功安裝好了,但要是自己的需求和資料稍有出入,自行修改了部份步驟,卻發現問題多多,心裡總有滿腹疑問,「為什麼不能這樣改?為什麼不能那樣改呢?」,會有這種問題的最根本原因是沒有足夠的概念,無法融會貫通。因此這篇文章的誕生就是為了幫助讀者建立觀念,以便更容易了解、吸收相關資料的內容。

從開機到進入作業系統經過了什麼地方?

按下電腦的電源鈕後,便由BIOS掌控大局。BIOS檢查完硬體相關狀況後,便會把主持棒交給MBR,然後再載入藏在MBR中的開機管理程式。這個藏在MBR裡面的開機管理程式會依照選擇而進入其他開機管理程式或是載入進入作業系統所需的核心,最後就進入作業系統。說了這麼一大串,大家應該都混亂了吧XD,

簡單來說就是:開機→BIOS→MBR→開機管理程式→(開機管理程式→)作業系統

MBR是什麼?

MBR全名是Master Boot Record,中文是「主啟動磁區」,也就是硬碟的第零軌。MBR的磁區大小為512Bytes,其中這又分成「Magic Number」、「Partition table」、「Bootloader」三個區塊。

Magic Number

存在於MBR的1~2Bytes,大小是2Bytes,中文是神奇數字!?(自己亂翻譯)。這個區域永遠填入固定的值「55AA」,事實上這個區域沒有任何特殊功能XD,只是讓其他程式可以辨認出這裡是MBR,簡單來說就只是一個識別碼。

Partition table

存在於MBR的3~66Bytes,大小是64Bytes,中文是「硬碟分割表」。裡面記載著硬碟各分割區的資料,例如:分割區的格式、分割區的起點與終點…等等。每一個分割區資料會花掉16Bytes,聰明的你,一定會發現,「那不就只能分割成4個分割區?」,為了增加可分割的數量,所以有一種分割區的格式是「延伸分割區」,裡面記載的不是真正的分割區資料,而是記載哪裡還有像硬碟分割表之類的東西。透過這種方法所建立的分割區,我們稱它為「邏輯分割區」。

Bootloader

存在於MBR的67~512Bytes,大小是446Bytes。這裡面放著一個開機管理程式(例如:GRUB),我們可以透過這個開機管理程式來載入作業系統所需的檔案,然後載入作業系統。又或者我們可以透過開機管理程式載入其他的開機管理程式。

開機管理程式放在哪裡?

每一個分割區的第一個磁區,我們稱之為「開機磁區」(Boot Sector)。開機管理程式可以放在MBR裡的Bootloader,或者是每個分割區的開機詞區裡。

為什麼MBR裡的Bootloader一定要存在一個開機管理程式?

因為BIOS做完他的工作後,會直接載入這個位置的程式。畢竟載入BIOS時,根本還不知道什麼分割區(因為那是下一個步驟才會載入的)。因此我們不能苛求它到處找開機管理程式,所以一定要在MBR裡的Bootloader地方放一個開機管理程式來接下主持棒。

一台電腦有幾個MBR?

這個問題看似困難,其實這個問題很簡單。想想他的定義:硬碟的第零軌。這時候你就會恍然大悟,原來有幾個硬碟就有幾個MBR。此時回想一下我們在設定開機順序時,不是可以設定要先載入哪個光碟機或是硬碟嗎?如果是選硬碟,就是指載入這個硬碟的MBR。

MBR修復程式是如何做到修復的?

MBR修復程式只會重新寫入「Magic Number」、「Bootloader」,如果是使用Windows 光碟片裡的程式「fixmbr」,他就會在Bootloader裡面重新寫入Windows的開機管理程式;相同的,如果是用GRUB相關的修復程式來修復,他就會在Bootloader重新寫入GRUB。至於「Partition table」則沒有修復程式可以幫你修復,畢竟每個人的分割區都不一樣。所以我們只能平常自行備份硬碟分割表,不過千萬要注意,不要備份在同一個硬碟裡面,不然到時候還是讀不到喔XD

rsync 中文說明

使用方式:

rsync [OPTION]… SRC [SRC]… [USER@]HOST:DEST
rsync [OPTION]… [USER@]HOST:SRC [DEST]
rsync [OPTION]… SRC [SRC]… DEST
rsync [OPTION]… [USER@]HOST::SRC [DEST]
rsync [OPTION]… SRC [SRC]… [USER@]HOST::DEST
rsync [OPTION]… rsync://[USER@]HOST[:PORT]/SRC [DEST]
rsync [OPTION]… SRC [SRC]… rsync://[USER@]HOST[:PORT]/DEST

我常用的大概就下面這個

rsync -rltvp –delete -e “ssh -p 1688 -l root” /home/user/chingwei/www/ xx.xx.xx.xx:/home/www/backup/www/

參數說明,網路上的中文說明好像都這份~~所以也不知道真正的出處在那。

  • -h , –help 顯示rsync求助資訊.
  • –version 顯示rsync版本.
  • -v , –verbose 複雜的輸出訊息.
  • -q , –quiet 安靜模式,幾乎沒有訊息產生.常用在以cron執行rsync.
  • -I, –ignore-times 通常rsync為了加快速度會忽略同樣檔案大小且同樣存取時間點的檔案.可以透過此參數關閉此快速檢查.
  • –size-only rsync只檢查檔案大小是否改變,不管時間存取點是否改變.通常用在mirror,且對方時間不太正確時.
  • -c, –checksum 在傳送之前透過128bit的md4檢查碼來檢查所有要傳送的檔案.(會拖慢速度.)
  • -a, –archive archive mode 權限保存模式,相當於 -rlptgoD 參數.
    很快速的保存幾乎所有的權限設定,除了硬式連結(透過-H設定).
  • -r, –recursive 複製所有下層的資料(遞迴)
  • -R, –relative 使用相對路徑.
    如:
    rsync foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo.c檔案
    rsync -R foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo/bar/foo.c 檔案
  • -R, –no-relative 不使用相對路徑.
  • -b, –backup 目的地端先前已經存在的檔案在傳輸或刪除前會被備份.
    –backup-dir=DIR 設定備份的資料夾.
    –suffix=SUFFIX 指定備份的檔案名稱字尾形式(預設為~).
  • -K, –keep-dirlinks 接收方將連結到資料夾的檔案視為資料夾處理
  • -l, –links 複製所有的連結
  • -H, –hard-links 保留硬式連結
  • -p, –perms 保留檔案權限
  • -o, –owner 保留檔案擁有者(root only)
  • -g, –group 保留檔案群組
  • -D, –devices 保留device資訊(root only)
  • -t, –times 保留時間點
  • -n, –dry-run 不實際執行傳送,只顯示將會有的傳輸動作
  • -S, –sparse 嘗試去處理稀疏的檔案,讓這些檔案在目的端佔去較少的磁碟空間.
  • -W, –whole-file 複製所有的檔案,不額外作檢查.
  • –no-whole-file 關閉 –whole-file 參數
  • -x, –one-file-system 不要跨越檔案系統分界(只在一個檔案系統處理)
  • -B, –block-size=SIZE 強制透過rsync程式去比對修復block-sizeforce
  • -e –rsh=COMMAND 定義所使用的remote shell
  • –rsync-path=PATH 定義rsync在遠端機器存放資料的路徑
  • –existing 只比對更新目的端已經存在的檔案
  • –ignore-existing 忽略目的端已經存在的檔案(也就是不更新)
  • –delete 刪除傳送端已經不存在,而目的端存在的檔案
  • –delete-excluded 除了把傳送端已經不存在,而目的端存在的檔案刪除之外,也刪除 –exclude 參數所包含的檔案.
  • –delete-after rsync預設會在檔案傳送前進行相關刪除動作確保接收端有足夠的檔案空間,但可以透過 –delete-after 讓刪除動作在檔案傳送後再行刪除.
  • –ignore-errors 忽略任何錯誤既使是I/O error 也進行 –delete 刪除動作.
  • –max-delete=NUM 定義rsync不要刪除超過 NUM 個檔案.
  • –partial rsync若遇到傳輸過程中斷時,會把那些已經傳輸的檔案刪除.在某種狀況下保留那些部分傳送的檔案是令人高興的.你可以透過 –partial 參數達到這個目的.
  • –partial-dir=DIR 在 –partial 參數啟動時,你還可以定義rsync把那些部分傳送的檔案寫入定義的資料夾,而非直接寫入目的端.需要注意的是,此資料夾不應該被其他使用者可以寫入.(如:/tmp)
  • –force 當目的端資料夾被傳送端非資料夾名稱覆蓋時,強制rsync刪除資料夾,即使該資料夾不是空的.
  • –numeric-ids 不將傳送端檔案的uid及gid值,與目的端的使用者/群組進行配對.若傳送端並沒有uid及gid的對應名稱(如:原帳號群組被刪除的遺留檔案),或目的端沒有相對應的帳號/群組,保留數字型態的uid/gid
  • –timeout=TIMEOUT 設定 I/O 逾時的時間(秒). 超過這個秒數而沒有資料傳送,rsync將會結束.預設為0,也就是沒有定義逾時時間.
  • -T, –temp-dir=DIR 定義rsync在接收端產生暫時性的複製檔案時使用資料夾暫存.預設是直接在接收端資料夾直接產生暫存檔案.
  • –compare-dest=DIR 定義rsync在目的端建立資料夾來比對傳送過來的檔案.
  • –link-dest=DIR 與 –compare-dest 相同,但同時會針對無法改變的檔案建立硬式連結.
  • -z, –compress 壓縮模式,當資料在傳送到目的端進行檔案壓縮.
  • -P -P參數和 –partial –progress 相同.只是為了把參數簡單化.
  • -C, –cvs-exclude 排除那些通常不希望傳送的檔案.定義的方式與CVS傳送相同:
    RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make .state .nse_depinfo *~ #* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj *.so *.exe *.Z *.elc *.ln core .svn/ 符合以上條件的都會被忽略而不傳送.
  • –exclude=PATTER 符合PATTERN(規則表示式)樣式的檔案不進行傳送
  • –exclude-from=FILE 和–exclude參數相同,不過是把不進行傳送的檔案事先寫入某一檔案.執行時,透過此參數讓rsync讀取.(; #開頭的行列或空白行會被rsync忽略)
  • –include=PATTERN 定義rsync不要排除符合pattern樣式的檔案.
  • –include-from=FILE 和–include參數相同,只不過把要包含的檔案寫到某一檔案.
  • –files-from=FILE 把要傳送的檔案名稱都精確的寫入某一檔案,讓rsync讀取.
    如: rsync -a –files-from=/tmp/foo /usr remote:/backup
  • -0 –from0 定義檔案所要讀取的檔案是null字元結尾.
  • –version 顯示版本訊息.
  • –daemon 定義rsync以daemon型態執行.
  • –no-detach 當以daemon型態執行時,不要進行分裂且變成背景程序.
  • –address=ADDRESS 定義所要連結(bind)的ip位址或是host名稱(daemon限定)
  • –config=FILE 定義所要讀取的設定檔rsyncd.conf位置(daemon限定) 預設值為 /usr/local/etc/rsyncd.conf
  • –port=PORT 定義rsyncd(daemon)要執行的port(預設為tcp 873)
  • –blocking-io 使用blocking I/O連結遠端的shell,如rsh , remsh
  • –no-blocking-io 使用non-blocking連結遠端的shell,如ssh (預設值)
  • –stats 顯示檔案傳送時的資訊狀態
  • –progress 顯示傳送的進度.(給檔案傳送時,怕無聊的人用的..)
  • –log-format=FORMAT 定義log的格式(在rsyncd.conf設定)
  • –password-file=FILE 從檔案讀取與遠端rsync伺服器連結的密碼
  • –bwlimit=KBPS 定義傳輸頻寬的大小(KBytes/秒)
  • –write-batch=FILE 把紀錄資料寫入一個檔案(給其他相同環境且相同需求的機器使用)
  • –read-batch=FILE 透過讀取紀錄檔案來進行傳輸.(檔案由 –write-batch 參數產生)
  • –checksum-seed=NUM 定義檔案 checksum-seed 的大小(byte)
  • -4 –ipv4 使用IPv4協定
  • -6 –ipv6 使用IPv6協定