使用bt4(Backtrack)破解无线路由(无线网络/无线AP)密码/wep加密/Aircrack-ng

前言

本教程,目的是让大家可以了解破解无线网络的方式,提高安全意识,加强网络安全。请不要用于非法目的。

另外,在互联网上,有太多的方法知道你是谁,不要以为用别人的AP就没法找得到你。

软件安装

使用bt的前提是下载安装,

可以参考这里

bt(Backtrack)安装教程http://www.path8.net/tn/archives/258

首先列出破解主要步骤[WEP 破解]

1) ifconfig -a

2) airmon-ng start wifi0 6

3) airodump-ng –ivs -w name -c 6 ath1

4) aireplay-ng -1 0 -e ap_essid -a ap_mac -h XXXXXXXXXX ath1

-1 is -one

5) aireplay-ng -5 -b ap_mac -h XXXXXXXXXX ath1

新的第5步: aireplay-ng   -3   -b ap_mac -h XXXXXXXXXX -x   1024   ath1

6) packetforge-ng -0 -a ap_mac -h XXXXXXXXXX -k 255.255.255.255 -l 255.255.255.255 -y fragment-XXXXX-XXXXXX.xor -w mrarp

7) aireplay-ng -2 -r mrarp -x 1024 ath1

aircrack-ng -n 64 -b ap_mac name-01.ivs

以下对上述步骤一一解释:

(运行这些命令都需要打开终端窗口,可以使用Ctrl+C 从文本文件Copy, 然后Shift+Insert 粘贴入终端窗口)

1)ifconfig -a

这个命令用于找到自己的无线网卡的 Mac地址。请记录下来备用。

2) airmon-ng start wifi0 6

这个命令用于将自己的无线网卡置于Monitor 模式,即类似一个AP的效果,因此可以有抓别人包的功能。

其中 wifi0 是我电脑里面给无线网卡的 ,一般应该都是这个,第一个ifconfig -a命令可以看得到。

wifi0 后面的那个6 ,是需要破解的AP的频道,如果不知道,可以在事前左下角开始菜单里面,找到 第二项 Internet 下面的倒数第二个画着 无线网的一个工具,用它可以看到那些需要破解的AP的频道(Channel)。

运行命令成功以后,你会看到返回的提示显示出现一个 Ath1(如果你是 Athoes的无线网卡的话就是这个,其他的可能不同,不过一般都是XXX1这样)

这个就是你的用于破解的网卡代号

这个命令,简而言之,就是把你的无线网卡置于监控模式,并且指定监控的频道。

如果你发现弄错了频道,那么没关系,重新运行一遍就可以了,不过这个时候,可能就会变成 Ath2…Ath3 等等,但是好像最多运行三次,然后就会失败。

3) airodump-ng –ivs -w name -c 6 ath1

这个命令比较关键,你运行以后,就会列出所有该频道的AP。

其中,6 是指你需要监控的频道,必须和第二个命令里的一样, ath1是刚才第二步出现的别名。

这个命令运行以后,显示的内容比较多,简单介绍一下:

BSSID : 其实就是AP的Mac 地址

PWR: AP信号的大小,一般,低于10,就比较麻烦了,丢包情况严重,比较难破解

RXQ: 干扰的大小

Beacons:发送接受的包,参考信息,在跳说明有数据

#Data: 这个比较重要,是接受到可以用来破解的特殊包,如果一直不变,那么,说明没有客户端连接,破解可能很麻烦,如果对方有大文件在下载,那么这个跳的速度非常快,10来分钟就可以有足够的包来破解了,如果跳得很慢,那么,就需要用一些特殊的方式来破解了。

CH:频道

MB:网络连接速度 54就是54MB

ENC, CIPHER,AUTH

这些是加密方式,我们这次只讨论显示为   WEP 和 WEP+ OPN的

如果显示 WPA TKIP 啥的,只能密码穷举破解,个人认为希望不大。

ESSID: 这个是AP的名字,需要用到的。如果是中文貌似会出问题。因此为了阻挡别人破解,可以用中文的ESSID

过一会儿,下面会显示哪些客户端连接到了哪些AP,针对有些Mac地址加密的,很容易模拟对方客户端的Mac从而骗进去,所以不要简单地相信Mac限制功能。

这个窗口就开着好了,不用关闭,以后的命令,需要重新打开一个终端窗口操作。

4)aireplay-ng -1 0 -e ap_essid -a ap_mac -h XXXXXXXXXX ath1

这一步开始,我们要做一些真正的破解工作,主要是针对那些客户端仅仅连接,没什么流量的AP,这种AP,#Data的增长非常慢,往往需要很长的时间才有 可能取得足够的包(一般5位的密码需要10000个包左右,更多的密码就要更多的。。。。)这个时候就需要 aireplay-ng 出面了,顾名思义,这个软件就是 Replay,也就是说,模拟发包。

首先解释命令:

-e ap_essid   就是   -e 之后加上你需要破解的essid ,比如 TP-LINK , linksys 啥的,注意大小写。

-a ap_mac   就是   -a 之后加上你需要破解的AP的Mac地址,第三步BSSID就可以看得到。不需要 :哦。

-h XXXXXXXXXX 就是 -h 之后,加上你的无线网卡的 Mac地址, 在第一步你可以得到。

ath1 ,上面解释过了。

一个样板例子:

aireplay-ng -1 0 -e TP-LINK -a 001900123456 -h 001900345678 ath1

这里有个小的建议,大家可以把以上的命令,都记录在一个文件里,然后把里面的XXXXXXXX都用自己的网卡Mac地址替换掉,这样就不需要每次都输入自 己的Mac地址了。每次都可以用Copy Paste的方式来输入,这样可以有效防止什么1 和 l , O和0 的混淆。

这一条命令,是用欺骗的方式,连接上那个AP,因此,如果网络信号不好,可能会执行不成功。

如果成功了,那么会显示Successful :>   字样。否则,请让信号强度大于10。

5)aireplay-ng -5 -b ap_mac -h XXXXXXXXXX ath1

上一条成功以后,我们需要开始收集那些需要的数据包,才能够进行模拟,并且破解。

所谓的需要的数据包,就是 #Data的数据,如果 #Data一直是0,那么可能会很麻烦,最好的情况是 #Data缓慢增长的这种情况。

解释一下

-b ap_mac 就是你需要破解的AP的Mac 地址,从第三步那里的 BSSID可以找得到。

-h XXXXXXXXXX   就是你自己网卡的Mac地址。

Ath1 和上面一样。。。。。

这一条命令的执行,和#data包有关,如果#Data 没有增加,则这个命令会一直执行,直到捕获一个#Data包。

捕获以后,程序会问你是否需要用这个包来模拟攻击。回答Y即可。

如果攻击成功,则会显示成功,失败往往是因为信号太差造成的, 如果攻击失败(往往是捕获的包有问题),程序重试N次以后,或自动重新开始捕捉包,继续进行即可。

等成功完成以后,会显示一个文件名:fragment-XXXXX-XXXXXX.xor

这个文件名,XXXXX里面是数字,是一个文件。马上会用得到。

这一步是最有可能失败的一步,尽量保持信号好一点。

6) packetforge-ng -0 -a ap_mac -h XXXXXXXXXX -k 255.255.255.255 -l 255.255.255.255 -y fragment-XXXXX-XXXXXX.xor -w mrarp

第六步,参数比较多,解释一下:

-a ap_mac 是待破解的AP的Mac地址,

-h XXXXXXXXX 是你自己的无线网卡Mac地址

fragment-XXXXX-XXXXXX.xor   就是第五步显示的那个文件名。

这一步会很快做完, 显示生成文件到 mrarp啥的,其实就是破解包的准备过程。

7) aireplay-ng -2 -r mrarp -x 1024 ath1

这一步没哈可以修改的,参数解释一下

ath1 是 你的无线网卡的名字

1024 是攻击速度,1024是最大值了,如果你的无线网卡不是MiniPCI的,个人建议设为 512 ,这样不容易死机。

当这一步开始执行,你会看到 第一个终端窗口里面,你破解的那个AP后面的   #Data在飞速增长,一般是 200个/s的速度,我们只需等待即可

8)我们可以新打开一个终端窗口,当 #Data达到 10000个的时候,就可以测试破解了,很多密码都可以 10000左右#Data就算出来

新窗口中运行:

aircrack-ng -n 64 -b ap_mac name-01.ivs

解释一下,

-b ap_mac 对方AP的Mac地址

name-01.ivs 其实是第三步自动生成的一个文件, 如果你多次运行了第三步,那么,可能会生成多个 name-XX.ivs文件, 你可以到对应的文件夹里看一下(就在桌面上的第一个文件夹图标里),找到XX最大的那个,就是你当前正在使用的这个文件。

-n 64 是指破解64位的密码,如果10万以上Data都破解不出来,那就试试 -n 128,估计这个兄弟用了128位加密。

运行以后,如果运气好,一会儿就会显示破解出来的密码,同时会显示 对应的Assic码,如果不是标准Assic码,就是一串数字,记录下来,搞掂。

运气不好的情况,这个程序会继续等待更多的#Data,等到了,就会重新计算一次密码。

小结一下:

本教程只针对 WEP 密码的破解,而且,最好有得到认证的客户端连接在这个AP上,如果没有,有些AP(比如TP-LINK)能够被破解,某些可能就无法破解。

本教程也提供了 模拟Mac地址从而破解 Mac限制的方法

如果你需要你的AP很难被破解,建议:

1)用WPA 加密方式,并且使用不可能被字典猜到的密码,目前还是基本可靠的

2)如果只支持 WEP加密,那么,尽量考虑用隐藏 SSID的方式,这样可以增加破解难度

3)如果只支持 WEP加密,那么,可以考虑使用中文名字作为SSID,这样基本问题不大。

4)一般破解时候,大家都会选择常用的频道,例如 6频道, 第三步显示频道的时候,你的AP也会被列出来,那么第一个目标失败的时候,黑客往往会选择第二个容易下手的目标, 但是如果你选择了8、 4、这些奇怪的频道,那么狠客往往懒得重新进入该频道的监控模式,你就可以逃过一劫。不过, 某些廉价AP,往往对6 频道做了优化,这个频道信号最强….这就没办法了。

5)有空换换你的密码:)

又注:联入网络以后,你可以管理他的AP,进行一些优化啥的,往往AP的密码,可能就是WEP的密码。

补充:

其中第5步:

aireplay-ng -5 -b ap_mac -h XXXXXXXXXX ath1 可以用新命令替代:

aireplay-ng   -3   -b ap_mac -h XXXXXXXXXX -x   1024   ath1

这一条命令可以自动地捕捉包,自动的发送包,自动的存为文件.

因此,这一步执行以后,如果开始正确的发收包,则可以看到 Data开始上涨,不过貌似速度会慢一点,用老命令的话,每秒500个增加,用新命令可能只有200个/秒

当足够多的数据包出现以后,可以直接运行第八步,跳过6\7两步.

**********************************************************************************************************************************

进入BT4系统

1:开第一个shell窗口,输入ifconfig -a 看到了瑞银网卡,显示为wlan0

2:输入ifconfig wlan0 up

再输入airmon-ng start wlan0   开启信道6的监听

3:输入airodump-ng --ivs -w name -c 6 mon0 截取数据包

7:建立虚拟连接:开第二个shell窗口,输入aireplay-ng -1 0 -a <目标AP MAC> -h <自己的瑞银MAC> mon0,当出现笑脸后连接成功

(这步很关键,不行的话就多试几次,输入iwconfig mon0 rate 2M 降低传输速度对建立连接有帮助)

8:aireplay-ng -2 -p 0841 -c ffffffffffff -b <目标AP MAC> -h <自己的瑞银MAC> mon0 进行交互式攻击。如成功输入Y确认

9:耐心等待第一个shell窗口的data的数字增加到1.5万以上

10:开第三个shell窗口,输入aircrack-ng -n 64 -b <目标AP MAC> name*.ivs

11:如果顺利,马上就能得到Key了

后记

最后顺便说一点,其实windows下也有一款破解无线密码的工具,WinAircrackPack,破解简单的wep密码非常快,操作比较傻瓜,如有兴趣也可以了解一下。

使用WinAirCrackPack在windows下快速破解无线网络密码

无线安全及Aircrack-ng for Windows破解无线wep,wap密码(附图)/教程 使用 用法 破解

Richard Stallman和自由软件运动

转自http://www.zeuux.org/philosophy/rms-and-fsm.cn.html

人类的进化史是一部人类为争取自由的战争史。虽然我不是人类学家,但这不妨碍我相信,在人类历史早期,人们所面临的主要困境是来自大自然的考验,比如:饥饿、严寒,还有那只隔壁山洞里嗷嗷乱叫的老虎。那时虽然环境艰苦,但人们是自由的,人与人之间是分享的、协作的。随着人类的“进步”,矛盾也逐渐由人与自然转变成人与人之间。我们从简单自由的原始社会进化到了尔虞我诈的商业社会,我们从通讯只能靠吼进化到了天涯比邻的信息时代。我们获得了更多的关于宇宙的知识,我们拥有了更加新进的技术,我们开始自以为无所不能。面对浩瀚的宇宙,我们不再敬畏,甚至已经对其置之不理。我们关注的是如何在竞争中取胜,如何通过专利限制他人。这时,一些原始社会的考验又重新回到了我们的身边:饥饿与严寒。不过,这次他们不再是来自大自然,而是来自那些利欲熏心的人们。现代社会正在将自由、分享、协作从我们身边赶走,我们还剩下什么呢?带着你的爱人和孩子去看看属于宇宙的太阳从地平线落下吧。不!它已经被固体可吸入颗粒漂浮物和高楼大厦挡住。我们剩下的只有回到钢筋水泥的山洞里为了晚餐和房贷的苦苦挣扎。在此,我不仅想和大家强调古人已经说过的“天下兴亡,匹夫有责”,我还想告诉大家计算机软件的历史也与此类似。

软件天生就是自由的

最初的计算机就像我们先人发明的算盘一样,只有硬件,没有软件,是一个纯粹的机械装置。直到20世纪中叶,随着电子管、晶体管的发明,计算机的电子成分才超越了机械成分,逐步演化成了现在的电子计算机,在这个过程中,出现了软件,并起到越来越重要的作用,最终成为了计算机的灵魂。最初的软件世界里,当然没有自由软件、专有软件、开源软件这些概念,因为软件天生就是自由的,公司在出售的硬件里附带了软件,包括源代码和文档。人们根据自己的需要,修改软件,自由地使用硬件,人与人之间互相分享,协作。关于这方面的经典故事就是Richard Stallman经常举例的“打印机驱动程序”的故事,它生动地展现了软件从天生的自由转向后天的不自由给人们带来的影响。

在哈佛大学读书的时候,Richard Stallman开始在MIT人工智能实验室工作了,成为程序员社团的一份子,大家彼此分享软件,共同努力增长人类知识,这是生活的一部分。MIT人工智能实验室买的第一台打印机附带有驱动程序的源代码,MIT人工智能实验室的黑客们可以自己修复打印机驱动程序的bug,或者根据自己的需要修改打印机的驱动程序,这为他们的工作带来了很大的方便。后来,MIT又买了一台激光打印机,这次厂商只提供了二进制的打印机驱动程序,它是MIT仅有的一个没有源代码的软件。出于工作的需要,Richard Stallman想修改一下这个驱动程序,但是他无法做到,因为他没有驱动程序源代码。后来Richard Stallman听说卡内基.梅隆大学有这个打印机的驱动程序源代码,他就去了那里,对他们说:“我是来自MIT的朋友,能不能把打印机驱动程序的源代码给我拷贝一份?”。Richard认为大家都属于计算机社团,他们肯定会给他源代码。但是他们拒绝了他。因为他们和厂商签署了一份保密协议,协议要求他们不能向别人拷贝源代码。顿时Richard Stallman感到他们背叛了自由的计算机社团,非常生气,一句话没说就回去了。

上帝说:“创造Richard Stallman吧!”

随着计算机工业的飞速发展,从20世纪70年代开始,原本自由的计算机社团渐渐地发生了变化,新兴的计算机公司从自由的计算机社团里雇佣走了大量的黑客去开发专有软件。他们在分发软件的时候不再附带源代码,剥夺了人们通过修改软件来使用计算机的自由,通过许可协议,将人与人之间的分享、协作赶走了。Richard Stallman成为留在MIT人工智能实验室的最后一名黑客,自由的计算机社团濒临崩溃。1976年2月3日,比尔·盖茨发表了著名的《致电脑爱好者的一封公开信》,抱怨未经授权使用Altair BASIC的情况太普遍,掀开了通过专有软件剥夺人们自由使用计算机的大幕。也正是从这时起,软件群体逐渐分化成自由软件社团和专有软件公司两大阵营。

the open letter of Bill Gates

Bill Gates: 致电脑爱好者的公开信

上帝说:“创造Richard Stallman吧,由他去发动一场捍卫人类在数字时代自由的战役!”。因为这不仅仅是一个技术问题,更是一个社会问题、伦理道德问题。既然软件是计算机的灵魂,那么它必须是自由的,不能被少数的专有软件公司所控制。很显然,首要的任务是开发一个自由的操作系统,于是Richard Stallman发起了GNU工程(http://www.gnu.org),为了保证自由软件运动能够长期发展下去,他创立了自由软件基金会(http://www.fsf.org)。在法律方面,他创造性地提出并实现了“对称版权(copyleft,笔者认为在此之前copyleft的中文翻译都不够好,所以创造了“对称版权”这个中文翻译,我将会在后续的文章里解释为什么“对称版权”能更好地反应copyleft的内涵)”,GNU GPL等。经历多年的自由软件运动之后,现在我们再次拥有了自由的、完整的操作系统:GNU/Linux,在GNU GPL授权保护下,我们拥有了大量的自由软件包。现在,只要坚持使用自由软件,我们再次拥有了控制自己计算机的自由。

1953年,Richard Stallman生于美国纽约曼哈顿区。在度过了并不快乐的童年之后,他在哈佛大学找到了自己的家。在MIT人工智能实验室工作期间,展露出了自己的计算机天赋。对他来说,开发操作系统就像喝水一样,是件很自然的事情,他主要的计算机软件作品包括:emacs、gcc、gdb等。随着专有软件的日渐流行和自由软件社团的日渐瓦解,Richard Stallman作为自由软件运动的领袖走上了历史舞台,为了捍卫人类在数字时代的自由,他高瞻远瞩,坚持原则,不为各种诱惑多动,始终将自由凌驾于其他任何东西之上,展现出了高尚的道德情操,让世人景仰。如今Richard Stallman已经功成名就,誉满全球,他是麦克阿瑟天才奖得主、美国国家工程院院士、美国艺术与科学院院士、数个大学的名誉教授等等。和这些名头比起来,大家更习惯把他称为自由软件运动的领袖,对此,他是当之无愧的无冕之王!

在2005年9月Stallman访华期间,我和洪峰、宫敏一起陪同他参加各种活动。生活中的Richard Stallman更像一个和蔼、安静的大叔,但偶尔也会暴躁、强硬。他酷爱中国美食,访问期间的每顿饭都给他安排不同的风味,都是他自己亲自点菜,并且详细询问每道菜的原材料,做法等细节问题,除了好奇之外,也要非常明确地知道自己吃了什么东西(需要知道菜的源代码),他不爱吃辣的东西,也不爱吃苦的龟苓膏。在吃饭的时候,他习惯于一边吃东西,一边打开笔记本电脑,记下自己的吃后感,然后发表到他在自由软件基金会网站的博客上。他不吸烟,也禁止他人在饭桌上吸烟,唯一的一次例外是容忍了宫敏博士的一支烟,因为在陪同Stallman期间他已经憋的太久没有吸烟啦。Stallman讨厌任何形式的运动,认为运动很无聊。所以看到他日渐增大的肚子,我很担心他的身体状况。

Stallman衣着简朴,不追求物质享受,如果估量一下他全身上下的衣着、随身的背包,价值应该在100元人民币以内。在北京期间,Stallman穿的鞋已经坏的不行了,我和洪峰在双安商场为他买了一双新鞋。伟大的Richard Stallman在买东西上并不那么伟大,面对琳琅满目的鞋子,Richard Stallman说的最多的就是“I don't know和I am not sure.“。Richard Stallman喜欢舒适的运动鞋,他的脚很大,我们找了半天也没找到合适的。在试鞋的时候,Stallman最强调的就是要防滑。有一次,他在瑞士访问期间滑倒了,胳膊卡到了楼梯櫈上,先后动了3次手术,现在左臂肘关节上还留有明显的伤疤。所以他现在最怕的就是滑到,要求鞋子能够帮助他站稳了。即便在这样的情况下,他仍然拒绝购买登山类的鞋子,他认为这样的鞋具有一些他不需要的特殊功能,另外这样的鞋也要更贵一些,他不想给朋友们造成经济负担。我们最终选择了一个白色的上面带有红色五星的CONVERSE牌子的运动鞋,价格是335元人民币,洪峰恰好身上没带那么多现金,他付了300元,我帮忙支付了35元,后来回到住处后,洪峰坚持还给了我那35元钱。另外,在买鞋的时候Richard Stallman抵制了adidas,nike这样的品牌,他说:“我只想买个鞋子,不想做广告”。

RMS tried the shoes

Richard Stallman在双安商场试鞋

为了在最大范围内推广自由软件,我帮助安排Richard Stallman和洪峰在新浪网做了一期在线视频直播节目,这样的活动在国内尚属首次。时下互联网媒体正助涨着全民走向娱乐的深渊,让Richard Stallman挤上这个以娱乐为主的舞台,传播自由软件思想,难度是非常大的。为此,我找到了新浪集团副总裁,CTO,李嵩波先生。李嵩波先生主管我们研发中心,为人谦和,平易近人,是新浪网的创始人之一,在美国硅谷工作多年之后,回到北京,执掌新浪的技术发展。李嵩波先生深谙技术,对Richard Stallman也是景仰有加,所以自然大力支持此活动。在李嵩波先生的亲自安排下,一切得以顺利进行。但有一个技术问题未能解决,国内的在线视频直播系统多采用微软的专有软件系统实现,新浪也是如此。Richard Stallman拒绝用专有软件来传播自由软件思想。这时,有人说如果采用直播的话,会有很多人看到您的在线访谈,非常有助于推广自由软件运动,Stallman的回答是NO,并解释道,如果他不这样坚持原则的话,自由软件运动早已夭折,不会发展到今天。自由软件社团有自由的、优秀的多媒体技术:Ogg/Theora。在短时间内将直播系统修改成theora/ogg格式难度较大,另外,这还涉及到用户的客户端软件。最后,我们采用了折衷的办法,将整个活动由直播改成录播,最后我将视频由wmv格式转化成theora/ogg格式再发布。

节目时间是2005年9月16日16:30-17:30,在访谈开始之前,安排了Richard Stallman和李嵩波的会面,在李嵩波的不大、甚至有些简陋的办公室(李嵩波将前任CTO的漂亮办公室改造成了用户体验实验室,用于接待新浪的网友做用户使用性测试,以改进新浪的产品和服务,他选择了旁边的一个小会议室作为自己的办公室)里,李嵩波、Richard Stallman、洪峰、黄冬和我等几个人进行了有趣的交流。Stallman还是一如既往地放松,进屋之后将背包仍到地下,脱下鞋子,开始和大家聊天。说着说着,他突然想起点事情,于是就弯下腰,去地上的背包里翻出一管药膏,然后开始脱袜子,嘴里一边和大家说话,一边往脚上图药膏,这就是Stallman,百无禁忌,自由自在。能够在新浪集团副总裁的办公室里脱鞋、脱袜子、上药膏的访客也就仅此一位吧。幸福时光总是过的很快,20楼的主持人开始催促我们去上节目了,于是我们大家一起动身去20楼,在20楼新浪巨大的标志前面合影留念。整个录播的过程很顺利,Stallman拥有非常丰富的演讲经验和语言魅力,在翻译的问题上,Stallman拒绝用和翻译交替说话的方式发表演讲,所以大家听到的都是流畅的英文。Stallman掌握面向母语是非英语人群的演讲技巧,所以即便是英语听力不好的朋友也都能听懂大部分内容,他会说的几句中文包括:“自由不是免费”,“曹操”等。晚上新浪公司宴请Richard Stallman和大家共进晚餐。

we are the world

左起:黄冬、洪峰、Richard Stallman、李嵩波、徐继哲

dinner

左起:徐继哲、Richard Stallman(感谢顾晓斌先生特异准备的红酒和月饼)

2005年9月17日上午,在中科院自动化所安排了一场演讲,下午我们陪他去王府井的外文书店买东西,他买了北京地图,还有他喜欢听的女子十二乐坊的CD。Stallman对书籍非常挑剔,那天没有选到自己满意的图书。在我们选东西的时候,他得知原本要在深圳接他去香港的朋友要去老丈母娘家过中秋节,不能接他了。他感到有些沮丧和无助。听到这个消息,我也感觉挺气愤,安慰了Stallman,并马上联系深圳的同窗好友卢振国,让他在去深圳机场接Stallman,并把他带到香港。他到香港后就有人为他安排后续的行程了。在此感谢振国,他在中秋佳节没有陪伴自己的亲人,而是和一个大胡子老外奔走在深圳机场到香港的路上。晚上的安排是去Beijing GNU/Linux User Group作演讲,我和宫敏陪同他前往。到了活动地点,发现BLUG的成员外国人比例很高,宫敏博士也在私下不无幽默地向我嘀咕“这里怎么都是洋人啊!”。虽然在自由软件社团里,我们要摒弃狭隘的民族主义,但北京GNU/Linux用户组如此高的外国人比例,还是让我们感到有些意外,这也反映出自由软件运动已经在西方世界深入人心,根深蒂固。

buy cd

Richard Stallman喜欢听女子十二乐坊的音乐,正在和宫敏精心挑选她们的CD。

Beijing GNU/Linux Club

在北京GNU/Linux用户组,左侧是宫敏。

2005年9月18日,星期日,中秋佳节,Stallman离开北京,前往深圳,转道香港,继续布道自由软件。北京交通拥赌,我们起早赶往首都国际机场,我担心Stallman没时间吃早餐,去味多美给他买了很多各种口味的点心,这些点心真派上了用场,不至于让Richard Stallman饿着肚子上飞机。那天,宫敏开车送Stallman去机场,也没有陪家人过好中秋节。而我和洪峰则快乐地陪着Stallman在机场过了一个快乐的、特殊的中秋节。在去往机场的路上,宫敏给洪峰出了一个有趣的数学题,洪峰师从吴学谋多年,数学功底很好,两人争论了半天。Stallman非常珍惜时间,在任何空闲的时间段都会拿出笔记本电脑来工作,在吃饭的时候、在排队的时候、在坐车的时候,只要有时间都会拿出笔记本来开始工作。他用的是一部已经使用很久的IBM T23笔记本电脑,操作系统是Debian GNU/Linux,平时的工作都在控制台下完成,工作环境当然都是emacs,很少去X下面工作,我见过他切换到X下面一次,他的X下只运行着一个Mozilla浏览器。Stallman收发邮件的方式也非常特别,他在自己的邮件服务器上安装了一个能够将收到的邮件打包压缩的程序,他在接收邮件的时候,就是将这个打包的文件下载下来,在等待下载的时候,他通常会选择玩一些控制台下的小游戏。在处理完邮件之后,会以类似的方式将这些邮件打包发送出去。Stallman总是奔走于地球的各个地方,这种处理邮件的方式非常适合他的工作。他也会经常收到一些用MS Office写的文章,他会告诉对方读不了这些文件,当然也会拒绝阅读这些文件。

为了能够在各种场合使用笔记本电脑,充足的电力供应是必须的,他特地为自己的笔记本电脑增加了一组外接电池,在我们一块儿休息或者吃饭的时候,他做的第一件事情就是找电源,给自己的笔记本电脑充电,以便将来能够随时工作。为了能够在站着的情况下也能使用笔记本电脑工作,他发明了一种有趣的方法:将一个长金属导线的两端拴在笔记本显示屏下的两个金属支架上,这样他就可以将这个和笔记本电脑连在一起的绳子套在脖子后面,再把斜挎着的背包放到身体的前面,然后把笔记本电脑放到上面,这样笔记本就被固定了,可以站着工作了。Stallman还是一个细节魔鬼,在办理包裹托运的时候,他会嘱托服务人员撕掉来时贴在箱子上的条码信息,以免和刚刚贴上的产生混淆。这就是Richard Stallman,自由软件运动的领袖,酷爱中国美食的山姆大叔!

waitting working

洪峰和Richard:等待办理登机卡,不能浪费时间,继续工作

自由软件运动发轫

大家都知道,如果没有操作系统,我们几乎没法使用计算机,可是在1983年,所有的操作系统都是专有软件,我们使用计算机的自由被剥夺了,少数的专有软件件公司控制了我们。于是Richard Stallman决定开发一个全新的、完整的、自由的操作系统,这样人们就可以用自由软件来操作计算机了。所以,请大家注意,自由软件运动的首要目标让用户拥有使用计算机的自由,让社会更加美好,人与人可以自由地共享知识,而不仅仅是要创造高质量的软件。即:自由软件反对的是专有软件,不是商业行为。事实上,Stallman可能是第一个将自由软件商业化的人,在创立自由软件基金会初期,为了能够筹集到资金支持自由软件运动的持续发展,他开始销售emacs磁带,并为用户提供技术支持服务,这和后来那些基于GNU/Linux的公司销售发行版光盘和提供服务没什么区别。在1984年,Stallman放弃了在MIT的工作,发起了GNU工程,次年创立自由软件基金会(FSF)。在那个时候,AT&T发明的UNIX已经非常流行,在UC Berkeley的努力下,功能已经十分强大,很多老的ITS黑客也都不情愿地转移到了UNIX下,逐渐喜欢上了UNIX的工作环境。为了让用户能够习惯新的、自由的操作系统,Stallman将GNU设计成与UNIX兼容,因此UNIX用户很容易使用GNU操作系统,所以GNU是类UNIX操作系统,GNU就是GNU‘s Not UNIX的递归缩写。在这个过程中,Stallman挽救了自由软件社团,使之重新走上繁荣之路。

在法律方面,Richard Stallman和自由软件基金会对人类贡献巨大。前几天,在和一个朋友聊天的时候,他说:“我知道你支持自由软件,但是不要走极端,去支持盗版”。听了这样的话,我真是哭笑不得,这也折射出很多人对自由软件运动还缺乏了解。事实上,自由软件社团对待法律的严肃程度远远超过了普通人的想象。我们不但不反对版权,反而非常珍视版权。Richard Stallman以现有版权体系(copyright)为基础,创造了对称版权(copyleft)。现行的版权系统赋予权力人和用户的权力是不对称的,这种权力的不对称性正在损害人类社会的整体利益。如今的专有软件公司正是利用了这种权力的不对称性,建立了以损害社会整体利益为基础的商业模式,在短短的20多年间,聚敛了富可敌国的财富。对称版权(copyleft)就是要赋予每个人平等的版权权力,但这不意味着大家的知识也会对称。即:对称版权不能推导出对称知识。这不是谁刻意造成的,这是自然规律。知识必须是公开的,自由的,不能有专利的,但这并不意味着会消除知识壁垒。道理是显然的,要攻克知识壁垒,需要付出稀缺的时间成本,有的时候,付出再多的时间成本也解决不了问题。比如,爱因斯坦的相对论都是公开的,可是地球上没有几个人能够理解,这就是知识壁垒,但是我们每个人都有权力去阅读相对论、去理解相对论。这就是对称版权(copyleft)主张的理念。所以,虽然对称版权(copyleft)发源自计算机领域,但是它的思想是具有普遍意义的,可以广泛应用于各个领域。在对称版权(copyleft)思想的指导下,Richard Stallman发明了GNU通用公共许可证(GNU GPL),GNU GPL是一个具有法律效力的自由软件许可证,在GNU GPL的保护下,已经涌现出成千上万的优秀的自由软件包。这些自由软件包赋予了用户使用计算机的自由。准确地说,自由软件对于用户来说具有如下4个自由度:

  1. 出于任何目的,运行软件的自由。
  2. 学习软件如何工作,以及为了满足自己的需要修改软件的自由。(显然,这个自由度的前提是能够访问软件的源代码)
  3. 为了帮助你的邻居,将软件拷贝给他的自由。
  4. 为了能够让整个社团受益,公开发行改进之后的软件的自由。(显然,这个自由度的前提是能够访问软件的源代码)

一个完整的操作系统是非常庞大的,是由编辑器、编译器、调试器、函数库、各种实用程序等很多部件组成的。所以,为了得到一个完整的、自由的操作系统,必须重新开发所有这些部件,这需要很长的时间。90年代初,在Richard Stallman和自由软件基金会的带领下,几乎做完了所有的工作,但是GNU操作系统还缺乏一个非常关键的部件:内核。1991年,Linus Torvalds写了一个操作系统内核:Linux。刚开始Linux并不是一个自由软件,但是在1992年,Linus将Linux的许可证改为GNU GPL,因此Linux就成了自由软件。Linux补充了GNU操作系统的空缺。于是,GNU和Linux结合在一起就变成了一个完整的、自由的操作系统:GNU/Linux。后来GNU/Linux越来越流行。人们发现它不光尊重你的自由,而且功能非常强大,非常稳定可靠,在很多方面都优于专有软件。

自由软件孕育了互联网

AT&T贝尔实验室在发行UNIX的时候都是附带源代码的,这种发行方式使用户学习、定制、改进UNIX成为可能。在UC Berkeley(加州大学伯克利分校),包括Bill Joy在内的一群天才黑客对UNIX系统进行了仔细研究,并增加了很多特性,以及大量的实用工具,比如vi,csh等等。渐渐地,UC Berkeley已经在UNIX里加入了很多自己的源代码,他们有机会将UNIX转变成自由软件,而且他们后来也真的这么干了,不过那已经是20世纪90年代初的事情了。在Richard Stallman刚刚发动GNU工程的时候,他就想到了UC Berkeley的UNIX发行版:BSD。他想说服他们将一些他们自己开发的软件转化成自由软件,这样就可以为GNU操作系统节省很多工作量,不必再重新发明轮子了,遗憾的是谈判进展的并不顺利。于是,Stallman决定发动自愿者重新开发操作系统的各个部件。

不同的人和团体有不同的价值观,在那个历史时期,要求别人理解Stallman的思想是困难的,因为他已经洞悉到了未来,尤其那时正是计算机工业腾飞的黄金时期,现在的许多IT寡头都诞生在那个时期。虽然UC Berkeley没有在第一时间意识到把BSD转化成自由软件的重要性,但还是做了一件具有历史意义的事情:他们在BSD上实现了TCP/IP。由于UC Berkeley强大的技术实力和良好的发行声誉,使得BSD成为最流行的UNIX发行版。很多其他操作系统的网络部分都是基于BSD的源代码开发的。所以BSD加速了互联网前进的步伐。经历20世纪90年代初与USL的那场官司之后,UC Berkeley CSRG发布了4.4BSD-Lite Release 2,CSRG小组解散。BSD转变成由来自地球上各个角落的黑客们维护、发展的一套操作系统,并逐渐演化出了NetBSD、FreeBSD、OpenBSD等版本。2003年,在FreeBSD的基础上,又发展出了DragonFlyBSD。这些BSD后裔传承了UC Berkeley严谨的学院派风格,同时又融入了来自互联网的黑客精神。从20世纪90年代初开始,一直发展到现在,在技术、管理等方面一直保持这领先的势头,让人尊敬。

据Torvalds说,如果没有当初那场官司,他可能不会去搞Linux,而是成为一名BSD黑客。在Linux后来的发展中,从BSD阵营借鉴了大量的源代码,才得以快速发展。不过Linux最终还是和GNU结合在了一起,组成了完整的操作系统:GNU/Linux。因为BSD即没缺过内核,也没缺过实用程序,它从一开始就是一个完整的操作系统。自由软件社团加速了互联网的发展历程,越来越多的节点、网站出现在了互联网上,他们在选择操作系统的时候也都优先选用自由、开放的操作系统:GNU/Linux、*BSD等。如今的巨型互联网公司,像Google,Yahoo!,新浪等,他们的服务基本都是建立在自由软件的基础之上。20年前,自由软件孕育了互联网;如今,自由软件支撑着互联网!

开源软件:那些放弃了自由的人们

到1997年为止,自由软件运动已经取得了相当大的成功。那时正值互联网迸发前夜,自由软件的概念也已经从深入民心发展到了华尔街,面临着巨大的商业机会。这时,有一部分自由软件支持者开始好了伤疤忘了疼。面对种种诱惑,他们将自由抛弃了。他们开始强调实用性,强调自由软件是好的开发模式,能够产生高质量的代码;他们开始以商业利益为诱饵去讨好公司的老板们,并提出了开源软件的概念,因为他们担心Richard Stallman的自由主义会吓跑那些唯利是图的商人们。其中的代表人物是Eric Raymond,一个彻头彻尾的实用主义者。专有软件公司们当然希望事态如此发展,所以在他们的蛊惑和支持下,开源软件概念迅速普及,电视、互联网、报纸、杂志等各种地方都充斥着“开源”,反而自由软件运动的发起者Richard Stallman、自由软件基金会和自由软件正在被人们渐渐遗忘。对于那些不了解自由软件运动历史的年轻人来说,他们一开始接触到的概念很可能就是抛弃了自由的开源概念,这是非常糟糕的。

实用当然没什么不好,但是为了实用就放弃了自由,那是愚蠢的短视行为。人类能够在地球上生存,需要呼吸、喝水、吃东西、居住等等,而SK-II和Ferrari却不是必须的。现在更多的人们已经意识到了这个问题,我们实在不应该以牺牲人类生存环境为代价来追求虚伪的东西,我们应该立即摒弃这种本末倒置的行为和想法。自由、平等是人类的基本权力,互助、分享是社会的存在基础,每个人都要珍视这些。遗憾的是,大多数现代商业都建立在剥夺人类自由的基础之上,软件业尤其突出。道理非常简单,这样的商业模式是利润最大化的,是容易形成垄断的。牺牲绝大多数人的利益来实现少数人的目标也是古往今来很普遍的做法,当然哪里有压迫哪里就有反抗,只是不同时期使用的手段和技术不同而已。在信息时代,我们以为自己的生活条件改善了,精神就容易懈怠,容易忽略与生俱来的那些珍贵的东西,自由、健康、友情等等。终于,专有软件包围了我们。在自由软件的概念正在被广泛接受和支持的时候,开源软件转移了人们的视线,将人们的思想从自由的高度降到了实用的低度。如果现在你还说这些无所谓,那么当你被抓到纳粹的集中营里任人宰割的时候会是什么心情呢?你害怕了,渴望自由了,渴望生活在阳光下了。在数字时代,这一切来的更隐蔽一些,水是被缓慢加热的,等你感觉到太热的时候,已经无力跳出。现在,你必须敏锐起来,不能等到你的计算机被人控制了、私人信息被泄露了、自己保存的文件被数字霸权管理(DRM)强行删除了、整天被病毒和流氓软件折磨着才做出反抗。那时,你一定会意识到自由的可贵,不过已经晚了。

所以自由软件的理念和提法更符合人民大众的根本利益,因此我们应该抛弃开源软件的概念。下图阐述了自由软件、开源软件和专有软件的关系。我们知道自由软件正给我们带来自由和光明;开源软件处在危险的灰色地带,正在左右摇摆不定;专有软件给我们的未来带来灾难。

free software, open source, ....

自由软件、开源软件、专有软件之间的关系,以及我们应该持有的态度

专有软件是毒品!

现在我们知道了软件团体如何分化出自由软件社团和专有软件公司,以及从自由软件社团里分裂出开源软件的事实。现在我们探讨一下专有软件的本质。专有软件的商业模式建立在剥夺用户自由、分裂社会的基础上,最终牺牲的是人类社会的自由度,所以专有软件更像是毒品和数字殖民。包括中国在内的很多国家,人们生活水平不高,版权意识淡泊,无力支付昂贵的专有软件许可证费用,最终习惯了去街边或者盗版专有软件市场花几块钱买上定价在几千元的MS Windows、MS Office和定价在上万元的Oracle回家使用,同时专有软件公司们扛着打击盗版专有软件的大旗来纵容用户使用盗版专有软件,设下一个圈套,等大家都进了这个圈套的时候,专有软件公司们就给这些可怜的人们当头一棒,这是典型的流氓行为。已经有很多公司深受其害,遗憾的是,更多的人和公司还没有觉醒,依然过着这种寄人篱下的悲惨生活。

专有软件公司更加深谋远虑,他们找各种冠冕堂皇的借口向学校免费提供专有软件,本质上是利用学校让学生患上专有软件成瘾症,成为他们的俘虏。可以确定,一旦学生毕业,这些公司再也不给这些人提供同样的、免费的专有软件。只有在学校使用的专有软件才是免费的,一旦你使用成瘾之后,就必须付费了。这些公司利用学校发放毒品,使大家成瘾,依赖这些专有软件公司。如果学校使用专有软件开展计算机科学教育,同时也将面临一个尴尬的技术问题:一名学生正在使用一个专有软件,他会对其某些设计和实现感到好奇,理所当然,他会问老师,这个功能是如何设计与实现的呢?这时,老师只能若有所思地转动一下眼睛,并尴尬地回答,我也不知道这是如何设计的,而且我们也不被容许知道,我们和专有软件公司签订了许可协议,这一切都是秘密。在这样的情况下,无法展开计算机科学的教育。

在开展知识教育的同时,学校也肩负着学生的道德教育,引导学生互助、分享,树立起自己的价值观,人生观,世界观,这将影响到学生的未来和社会的未来。专有软件将分享和互助从学生的身边赶走了,根据专有软件许可协议,为了帮助你的朋友,邻居,你没有权力将软件拷贝给他,只能自己地使用,这是一个严重的道德问题,学校的使命是培养未来的一代,使他们能够健康成长,能够独立地生活,给社会带来更加健康、和谐的东西,而不是生产冷冰冰的军事武器。因此学校应该拒绝接受专有软件,并告诉那些专有软件公司,我们不会给学生提供毒品,我们当然也不会给学生提供专有软件。

殖民和殖民地不是新鲜术语,不过我们要警惕在不同的时代的不同手段。在信息时代,稍有不慎,一个国家、一个民族就很可能被数字殖民,被少数人所控制。设想,一个国家的计算机操作系统、数据库、应用软件等都被几个专有软件公司控制,那是什么后果?不但在经济上受制于人,前途未来也蒙上了阴影。专有软件公司鼓惑你将数据都搬进专有软件里,在生活、工作中依赖专有软件,这时,他们就会露出丑恶的嘴脸和殖民的本性。对此,政府必须保持清醒的认识,将命运掌握到自己的手中。而自由软件为我们提供了千载难逢的机遇。

《黑客帝国》图解自由软件、开源软件、专有软件

《黑客帝国》是我最喜欢的电影之一,它不但画面精彩刺激,更重要的是内涵深刻。不像国内的那些大牌导演只会把钱都砸到电脑特技上,剧本简单的一张A4纸都能装下,把观众当成傻瓜。通过上边的赘述,我们已经了解到,如今的软件社团主要包括三种势力:自由软件社团、开源软件社团、专有软件公司。如果你一直坚持读到这里,那么我要感谢你的执着。也到了该放松一下的时候了,现在我们一起通过《黑客帝国》这部电影再次理解这三种势力。但愿你看过《黑客帝国》三部曲,否则无法理解。

和现在绝大多数人类已经被专有软件控制差不多,在2199年的某个时候,计算机已经控制了地球上的绝大多数人类。计算机设计并实现了一套近乎完美的仿真系统,Matrix,来控制人类。机器像种庄稼一样播种着人类,从出生到死亡人都是被放到一个固定的容器里,为庞大的机器帝国提供电力资源。性爱的快感已经变成了来自Matrix的模拟信号,人类已被完全控制,生活在虚拟的世界里,可自己却全然不知。所以,我们首先请出这一切的主谋:专有软件帝国的创始人Bill Gates和Matrix的秘密警察Agent Smith。

Gates & Agent

Bill Gates和Agent Smith

在如今这个专有软件还居于主导地位的世界里,Bill Gates正像Agent Smith一样扮演着维护世界和平的角色。在外界看起来,他带领的微软帝国正在为了让世界变得更加美好而努力工作,不断开发出新的产品和技术。可事实上呢?他正像计算机创造了Matrix一样,创造了专有软件体系,以牺牲整个人类社会的自由度为代价,实现着自己的人生目标。

哪里有压迫,哪里就有反抗!和现在已经有很多人通过坚持使用自由软件重新获得了使用计算机的自由的情形相似,在Matrix的严密监控下,还是有一部分人发现了事情的真相,并成功逃离Matrix系统,发动了为争取全人类自由的战役。他们处境艰难,势单力薄,不过他们最大的困难是如何将真理传达给Matrix系统中的人们,让那些误以为世界很美好的人们理解事情的真相。现在我们全体起立,鼓掌欢迎自由软件运动的领袖Richard Stallman和执着、坚定、矢志不渝的Morpheus,向他们致敬!

RMS & Morpheus

Richard Stallman和Morpheus

经过Richard Stallman、自由软件基金会和自由软件社团多年艰苦奋斗,在专有软件笼罩的黑色天空,已有很多地方开始泛白,真理的阳光正在更大范围内洒向人间。Richard Stallman先知先觉,发动了自由软件运动,他解救出了更多的人们,自由软件社团得以避免崩溃。在大家的努力下,GNU操作系统羽翼渐丰,可是GNU的内核,hurd,却一直在产前剧痛,迟迟未能降临。此时,在地球的一个寒冷角落,另一个人也感到了世界有些不对,他迷茫、困惑,下意识地做着一些事情,他开发了一个操作系统内核:Linux,他就是Linus Torvalds。Torvalds是技术天才,但还是个孩子,不了解世界的真相,他需要被引导,走上正确的道路。就像Morpheus找到了Neo一样,在自由软件精神的感召下,Linus Torvalds走上了正确的道路,将Linux改为GNU GPL版权,成为了自由软件,但仅有Linux是没用的,就像如果没有Morpheus的引导,Neo顶多是那家软件公司的高级职员一样。Linux只有成为自由软件,才能获得新生。幸运的是,最终Linux和GNU结合在了一起,组成了自由的、完整的操作系统:GNU/Linux。(此处需要说明,Linus Torvalds的重要性远远小于Neo;Richard Stallman的重要性远远大于Morpheus。在理解此处的时候,主要从工作内容的角度来考虑,为了体现人物的对应性和娱乐效果,经过前思后想,还是用了这2个人物对照。考虑到近几年Linus的一些做法,这是一个危险的甚至是错误的比喻!)现在有请Linus Torvalds和Neo,这两位天真的帅哥。

Linus & Neo

Linus Torvalds和Neo

任何一场伟大的战役都需要一个伟大的领袖,也需要一个知名的叛徒。Morpheus找到了Neo,酝酿发动决战。这时,他昔日的战友,Cypher,已经无法继续忍受这种吃不好、穿不暖的生活,而且Trinity也不爱他。他决定回到Matrix系统中,因为那里有美酒、烤肉和女人,Agent还答应把他变成一个明星,会非常的有钱。最终,Cypher背叛了Morpheus。自由软件运动也是如此,在GNU/Linux系统展现出巨大的自由价值之后,有些人开始忘记这场运动的最高目标:自由。他们关注的焦点是自由软件的商业机会,努力讨好那些打着领带的经理们,希望能够从中渔利,他们的代表人物就是Eric Raymond。我们现在就一起看看Eric Raymond和Cypher正在干什么?

ESR & Cypher

Eric Raymond和Cypher

事实上,Eric比Cypher的本事大多了,他不但背叛了自由,还大势宣扬开源的实用性,让人们更关注短期利益,反而渐渐遗忘了自由的可贵。使得努力拼搏得来的一些白色天空开始变得乌云密布。虽然如此,我并不认为开源软件是自由软件的敌人,至少还是我们的盟友,我希望那些整天将“开源”挂在嘴边的人士们重新认识自由,回到自由软件社团,一起与专有软件斗争到底。

如上也算是一个恶搞(parody),全当娱乐。能够帮助大家理解自由软件、开源软件、专有软件这三种势力,以及其中的核心人物。

新的威胁

斗转星移,如今的计算环境与23年前自由软件运动发轫之际相比发生了巨大的变化。近些年,又陆续出现了许多新的东西,进一步威胁人类在数字时代的自由,比如数字霸权管理(DRM)、软件专利、可疑计算(TC:Treacherous Computing)等等。这些新的限制手段都具有非常强的迷惑性,人们很容易上当。前几天,我和Richard Stallman专门就数字霸权管理(DRM)展开了专题讨论,大家参见《阻击数字霸权,捍卫人类自由》,以后我们会继续专题论述这些新的威胁。面对这些威胁的步步紧逼,自由软件社团已经采取了积极的措施。目前正在地球范围内公开征集GNU GPL v3的修改意见,我们将通过GNU GPL v3阻击这些威胁。在2006年,自由软件社团将越过已经坚守了23年的防线,向专有软件发起进攻。这些威胁关系到我们每一个人的自由,我们不可以袖手旁观,更不能视而不见。天下兴亡,匹夫有责!

几点期望

经历了23年的自由软件运动之后,自由软件已经取得了巨大的成就,在研究、教育、出版、互联网、IT工业、法律等领域显示出了巨大的价值和旺盛的生命力。为了自由软件运动能够在未来的日子里一如既往地成功,请加入自由软件社团,支持自由软件运动。在此,我有几点具体的期望,希望读者能够在读完此文之后身体力行:

  • 立即将专有软件从你的生活、学习、工作中踢出去,全面采用自由软件。
  • 当你在称呼一个完整的操作系统时,请用正确的名字:GNU/Linux。
  • 从开源软件回到自由软件社团的怀抱,以后使用“自由软件”这个术语。
  • 本文属于普及概念性读物,请读者在非商业用途、保持文章完整性、逐字逐句的情况下传播此文章。

最后,我呼吁大家加入自由软件社团,投入到为捍卫人类数字自由的战役中!

[转]Linux之父 Linus Torvalds 李纳斯·托沃兹

[很老的一篇文章 from pconline 2005年02月05日]

http://www.pconline.com.cn/pcedu/empolder/life/0502/551320.html

自由软件 Linux 之父:李纳斯·托沃兹(Linus Torvalds)

导语:28岁的芬兰青年李纳斯创造了一个全新的世界:就是一种名为Linux的操作系统。它所产生的力量决定了编程领域的新氛围,正如我们的环境决定了 动植物的特性一样。创造简洁优雅的程序,写出干净而无冗长的代码,或者是超一流的程序,就足以赢得同行们的尊敬和推崇。而李纳斯走得更远,他不但重新定义 了一流程序、代码和软件的基准,而且迈向了“黑客”的终极高度,开创了另一个互联网的传奇故事。

21世纪是自由软件的世纪

好像是谈论梦想,又好像是“X档案”中的一段情节。一个21岁的芬兰大学生,在学生宿舍里写了一个操作系统的内核——Linux,然后公布于众,吸引了成千上万的程序员为之增补、修改和传播,短短几年就拥有了1000多万的用户,成为地球上成长最快的软件。

就在两年前,你去问一个程序员自由软件的前景,他肯定会告诉你,自由软件有意思,但难成气候。而今,无数的程序员都将Linux作为自己首要的追求,否 则不足以证明自己的境界。就在一年前,你去问一个大公司的信息主管有关自由软件的可行性,他肯定会告诉你,这东西他不会、也不敢用,因为缺乏相应的支持, 缺乏应有的商业化质量。

但今天,局势大变。《幸福》500大企业的信息主管已经纷纷在着手Linux的评估和部署。而且,在不到一年时 间内,Linux就得到了IBM、HP、Compaq、Sun、SGI、Dell、Oracle、Informix、SAP、Sybase、CA、 Intel、SCO等除微软之外的几乎所有计算机大公司的支持。虽然已被一群信徒崇拜多年,Linux,这个稳定、开放、可靠、廉宜的操作系统,只有在 1999年才堂而皇之跻身业界主流,成为微软帝国合法的竞争对手。而且,成为地球上最炙手可热的软件。

一台邮件服务器成年累月运行,却 从不需要重新启动;一台网络服务器面对海量访问,却从不崩溃;一个操作系统还带源代码,可以自由地无限制地修改。这一切,听起来可望不可及。但实际上,数 以千百计的公司真的找到了实现了网络零故障的秘诀。而且它不是Windows,而是Linux。

光芒四射的Linux凭借产品的卓越 脱颖而出。毫无疑问,这要归功于世界各地无数富有才华却又不计报酬的黑客(特指执着狂热的程序员),尤其是李纳斯·托沃兹创世纪般的贡献。曾经被无数个巨 头公司猛烈攻打,而屹然不动的微软帝国,如今,有可能被一个人发动的战争所摧毁。

因为Linux不仅仅是一个产品,其背后有着人性中最 悠久的底蕴,有着自由软件深厚的传统,又有着互联网势不可挡的自由共享精神的背景。而且它所摧毁的不仅仅是一家公司,而是整个软件产业封闭的传统商业模 式。因此,Linux掀起的不只是一场战役,而是一场影响深远的革命。它的直接作用就是打破软件世界的单极垄断,瓦解软件业的知识霸权。它的深层意义就 是,将软件业从系统集成和产品制造为中心的低级阶段推向以服务为中心的高级阶段。

Tim Oreilly说,自由软件将像“Intel Inside”,成为计算机业的下一波浪潮。更有人直截了当地说:“21世纪将是自由软件的世界”。

正如互联网难以置信的爆炸一样,自由软件也是不可思议地猛推到人们面前。已经习惯了风暴式创新的信息产业,仍然被自由软件无以伦比的声势所震撼。但是,至今还有许许多多的人对这场革命无所适从,或茫然无知。

芬兰的荷马史诗

一个冬天只有三个小时日照,夏天几乎全天日照的芬兰,约1/4的国土处在北极圈内。这个寒冷的国度,遍布 着大大小小约60000多个湖泊,芬兰也因此被人们称为“千湖之国”。在芬兰,一年中实际上只有三个季度,即春冬、夏季和秋冬。“严寒的冬天”长达8个月 之久,而夏天却只有60天左右。芬兰的历史可以说是芬兰人与自然、与寒冷做艰苦卓绝斗争的一个神话。

芬兰人的民族史诗《卡勒瓦拉》就记 载了这个民族从远古时代,直到圣女玛丽亚生下英雄卡勒利亚王为止的所有神话。这部史诗的作者从丰富的民间传说、神话及歌谣中汲取了一切养料和精彩篇章,将 它们收集、改编并润色整理。1835年初版时有35篇长诗,共12000多行;而1849年再版时,篇幅几乎增加了一倍,共50篇长诗,23000余行, 是由数千年的民间传说拼凑而成,最终成为芬兰人的“荷马史诗”,对芬兰语言的形成和国家的文化起到了极为重要的作用。该诗的主人公是一个道士 Vainamoinen,最终则成为世界的主宰。

虽然卡勒瓦拉是一个虚构、夸张的故事,但它与现实世界中的另一部“杰作”非常相似,这 部杰作就是由互联网促成的,是由成千上万名不同的黑客相助的结果。而始作俑者就是28岁的芬兰青年-李纳斯·托沃兹,他创造了一个全新的世界:Linux 的操作系统。它所产生的力量重新定义了编程领域的全新氛围,正如我们的环境决定了动植物的特性一样。

对大多数黑客来说,他们的目标就是创造简洁优雅的程序,干净而无冗余的代码。或者是超一流的程序,以此赢得同行们的尊敬和推崇。而李纳斯走得更远,他不但重新定义了一流程序、代码和软件的基准,而且迈向了“黑客”的终极高度。

Linux的装机量还无法与Windows的1亿多用户相比,甚至还不能与苹果Mac的5000万用户相比,但是Linux的崛起势头却令人咋舌。由于 它可以在互联网上免费发送的,因此在那些互联网发达的国家十分流行,例如南非、古巴、墨西哥、斯洛文尼亚、克罗地亚、俄罗斯、印度、巴基斯坦、尼加拉瓜、 菲律宾、玻利维亚等。从技术上讲,Linux使其他品牌的Unix黯然失色,成为Unix市场最重要的组成部分。连Unix最早的共同创始人Dennis Ritche也说:“Linux值得称赞。”

Linux的传奇还有许多线索,但它的主角就是李纳斯。这是一位具有非凡智慧和魅力的黑客,他单枪匹马能解决的问题,往往要让一群程序员苦干数月。当然,这也是一个互联网的传奇故事,是依靠互联网分布式协作模式的成果。

事实上,Linux是互联网的卡勒瓦拉,这个巨大的代码拼凑物代表着这个快速增长的电脑王国。它将开发者和使用者紧紧地联系在一起,将这么多程序员连结 在一起的最大动力就是要创造出世界上最伟大的操作系统。它比任何一种商用Unix都要强劲,可以运行在各种硬件平台上,而且可以无限制地按需定制。这个操 作系统可以完全与微软的旗舰产品Windows NT相媲美:具有真正的多任务功能、虚拟内存、共享库、TCP/IP网络以及其他各种先进性能。许多人都将它视为NT最强大的竞争对手,也是微软垄断下的 唯一可替代的选择。

一个大鼻子的书呆子

“我是在大学校园的游行示威中诞生的。我们家的爱巢修筑在我祖父公寓的一个房间里。我的第一个摇篮是一个洗衣用的筐子。幸好那个时期没有给我留下什么记忆。

我是一个长相丑陋的孩子。要是好莱坞有一天想拍一部关于Linux的电影的话,我希望他们一定得找一个像汤姆·克鲁斯那样的人担当主角,但在现实中,我的相貌可没有那么好。千万别误解我的话,我还没丑到《巴黎圣母院》里那个驼子的地步。

但可以想象一个我的大包牙,凡是见过我小时候照片的人,都会觉得我的相貌酷似河狸。再想象一下我不修边幅的衣着,以及一个托沃兹家族祖祖辈辈遗传下来的 大鼻子,这样,在你脑海中我的模样就形成了。有时别人对我说,我的鼻子长得简直“富丽堂皇”。照片上我们家三代男人的脸部轮廓让人痛苦地联想到,留在别人 记忆里的唯有鼻子而没有什么其他的男人气质。

为了让你对我模样的想象更完整一些,现在再来补充一些细节。棕色头发(在美国这里,人们把它称做金黄色,但在斯堪的纳维亚就叫做“棕色”)、蓝眼睛、稍有点近视,于是戴副无伤大雅的眼镜。另外眼镜至少可以让人不大注意我的鼻子,于是我就带上了,任何时候都不摘下来。

我在穿着方面的缺乏品味。通常,我都是选深蓝色的衣服,这就意味着我只穿蓝色牛仔裤,再配一件蓝色翻领毛衣——也可能是青绿色之类。

这些都没什么影响。因为,我有迷人的个性。

我是一个古怪的书呆子,一个为人取笑的对象。我有着其他合乎大家想象中的书呆子的所有特点:比如数学极好,物理也非常棒,社交能力却差得一塌糊涂等等。每一个人大概在上学时都遇到过像我这样的人:在数学方面很突出,但不是因为学习刻苦,而是天生就是那个样子。

我可能的确很怪,而且是个小矮个,但我混得不错。我在体育方面虽说不上能达到运动员的水平,但也不是不可救药的家伙。我没花什么力气就成了在学校里属于 有点档次的那类学生,尽管从来也不属于出类拔萃的那种,可能主要是因为我不那么玩命。其实我即使在社会层面也有别人可以接受的地方。好象谁也不会太关注我 的鼻子。

回过头来看,当时的大多数孩子似乎在穿衣服方面也不太讲究,而当我们长大后,又突然要由别的什么人来决定我们穿什么衣服了。就 我自己而言,这些人主要是某些高技术公司的销售人员,我就穿他们在会议上免费发送的T恤和夹克。而且我还有一个老婆,由她决定我的衣橱里应该放些什么样的 衣服,还替我挑选凉鞋才袜子。于是我更用不着为此事操心了。

我的鼻子越长越大。但至少现在,与我的鼻子相比,我的人格力量占了上风。”

终极黑客出手

Linux这部史诗发端于赫尔辛基。似乎天下的黑客都在为自己的生命创作源程序,李纳斯也不例外。他的家 就在离市中心不远的Kalevagatan(与卡勒瓦拉很相近)大街。这是一个19世纪的建筑与现代化平房交相呼应的地方。李纳斯与妻子住在这里。他的家 很像是大学生的集体宿舍,楼梯下总放着一排排自行车。

李纳斯本人看起来就像一名学生,而不像道士。他中等身材,浅褐色头发,蓝眼睛,目 光透过镜片直直地射向你,只有浓密的眉毛是黑色的,衬着一张孩子气的脸庞。他的房间四周排列着许多书籍,里面布满了油画和各种装饰品,相当低廉的窗帘,两 把扶手椅之间挂着发干的鳄鱼皮,房间里还有两只目空一切的猫和几台计算机:三台PC,一台Power Mac,还有三台从DEC借来的基于Alpha芯片的微机。它们不起眼地布置在房间的角落中。另外一样很有意思的东西不易察觉:那是一根将计算机连到电话 插座的导线,这是通向互联网的256K的专线,由当地的一家ISP安装并承担费用,它是对这位Linux道士的象征性奖励。

Linux 并不是一件刻意创造的杰作,而完全是日月积累的结果,是经验、创意和一小块一小块代码的合成体,不断的积累使其成为一个有机的整体。Linux初期的许多 编程工作是在Sindair QL机器上完成。这台机器化掉了他2000多美元,对他来说,这可是一笔“巨额”投资。这是一种十分古怪的英国产电脑,是1984年推出的。它有无数的缺 点,却有一个真正的优点:它是一套真正的多任务系统。有一件十分关键的事件最终导致了Linux的诞生。

“上大学第一年我的宿舍在一 层,靠窗户的一张桌子上就摆着Sinclair QL电脑。但我没有编写多少程序,原因之一是我必须集中精力读书,原因之二是我也找不到什么项目去做。没有项目可做就会缺乏热情。你总是在寻找能够让你鼓 起劲去做的事情。当时似乎是参军的好时光。我当时十九岁,正因为自己的电脑毛病太多而心情沮丧。而且,当时也没有任何有意思的电脑项目,于是我就搭上了一 辆开往拉普兰的火车。在那里手执武器上了一个月的“体育课”之后,我便觉得在我有生之年完全有资格从此一动不动,享受平静的生活了。惟一可做的事情就是把 编码打入键盘,或者手里端着一瓶比尔森啤酒(说真的,在我复员整整十年后,才第一次参加一次剧烈的活动。当时大卫硬拉着我去冲浪。旧金山半月湾的强大海浪 差点没把我淹死,我的腿一连酸了好几天)。

部队服役结束于1990年5月7日。我连我们的结婚纪念日都记不住,但我却不大可能忘记我离开部队的日子。

那年整个夏天我没有干什么正事。我大学二年级的课程直到秋天才开始。我的电脑状态也很不佳。于是我就穿着一件破旧的睡衣,逗猫玩,偶尔和朋友们联欢会,让他们笑话我的保龄球和台球的拙劣技术。当然,我对我的下一部电脑也做了一些设想。我面临的是一个电脑迷的困境。”

1990年秋天,李纳斯在赫尔辛基上Unix课程。学校刚刚安装了一台运行Ultrix(Unix诸多版本中的一种)MicroVAX。Unix是大学 科学和工程院系最流行的操作系统,那些处理繁重任务的公司也使用Unix。Unix的问世与互联网的历史密不可分。事实上,互联网上运行的大多数操作系统 都是Unix。1993年,AT&T将Unix卖给Novell。1995年,Novell又将它卖给圣克鲁斯丁。如今,像SCO、IBM、 DEC、HP和Sun等都有不同的版本,造成了市场的混乱,成为微软Windows攻击的致命弱点。

但1990年,李纳斯还沉浸在许多 世俗的事物中。由于大学的机器无法同时处理16个以上的用户,要用机器,就得排长队等待。那时李纳斯刚刚得到一台PC。他从笨拙的DOS操作系统学不到任 何东西,而他的课本中就有安德鲁·塔南鲍姆(Andrew Tanenbaum)的《操作系统:设计与实现》,该书提供了Minix(Unix的变种)的操作指南。Minix虽然很简单,功能有限,但是Minix 却在李纳斯的脑海中奏出一个和音:“1987年发布后两个月来,就有一个新闻组汇集了世界各地的40000名用户。”许多用户需要更多的功能。塔南鲍姆 说:“我每天都收到几百个电子邮件,要求增加这个功能、那个功能。但我只能一再回绝,使许多人都非常沮丧和失望。”

“每个人都会一本改变其一生的书籍,比如《圣经》、《资本论》等等,而那本红色的简装本教科书差不多等于睡在了我的床上。”

Linux创世纪

李纳斯开始自己试验性地编程,他将Minix当作脚手架,开发一个新的程序。他按两个过程进行,一个过程写A,另一个过程写B,但他从来没有想过要创建一个内核(操作系统中用于实时处理和控制工作的部分)。他只通过阅读新闻组来修改两个处理过程。

李纳斯很早就是一名黑客,“如果说我孩提时代一些最幸福的记忆是玩我外公的一台老式电子计算器,对此大概谁也不会感到惊奇。我外公是赫尔辛基大学的一位 统计学教授。那时的计算器可不像现在的那样能够很快的一下就给出答案,它们还得有个计算过程。一边计算一边闪烁个不停,好像在对你说:“瞧,我还活着,这 次计算我只用10秒钟就能完成,同时我还能对你眨眼睛,告诉你我已经完成了多少工作。”

这一点非常有意思。比现在的计算器令人兴奋多 了,因为现在的玩意儿在计算简单问题时全然不费力气。而当早期的计算器计算时,你知道它们正在辛苦地工作。并且,这一点可以一目了然地看出来。大概是在 1981年,当时我外公抱回来一台崭新的Commodore VIC-20计算机。刚开始还比较有节制,后来简直就被它迷住了。

我开始用数字形式编写程序,然后再用手工进行转换。这就是用机器语言编程序。我已经能够驱使电脑做事情,对一切细节我都能够加以控制。由于在我和电脑之间没有抽象的屏障,我很快地就能接受目标,这便是和一台机器变得亲密的感受。

就这样,十二岁、十三岁、十四岁过去了。其他孩子在外面踢足球的时候,我却觉得外公的电脑更加有意思。我每个礼拜开一次会,这是在我的日历上唯一的社交活动,偶尔和电脑一同熬夜时除外。

外公死后,他的电脑就成了我的生活伴侣。

由于我父母的离婚,我们手头很拮据。当时我记得最清楚的是,我妈妈不得不经常典押她唯一的投资——无度电话公司的股票。在芬兰,只要你拥有一部电话就能 拥有一张该公司的股票。我妈妈的股票大约值五百美元,每当我们手头特别缺钱花时,她就只好拿着股票到当铺去。我记得曾和妈妈去典押过一次,心里感到非常窘 迫(如今我是这家公司的董事会成员。事实上,赫尔辛基电话公司是我任董事会成员的唯一一家公司)。”

1991年,他需要一个简单的终端模拟程序来访问新闻组。于是李纳斯坐下来,写了一个基于两步处理的应急程序。工作内容非常简单,一个过程就是从键盘中读出并发送到Modem上,另一个过程就是从Modem上读取并发送到屏幕上。

1991年夏,也就是李纳斯有了第一台PC的六个月之后,李纳斯觉得自己应该下载一些文件。但是在他能够读写到磁盘上之前,他又不得不编写一个磁盘驱动 程序。同时还要编写文件系统。这样有了任务转换功能,有了文件系统和设备驱动程序,就成了Unix,至少成了 Unix的内核。Linux由此诞生了。

再一次走在了自己的前面

“坦白地讲,在使用UNIX的人当中,有许多是几乎发疯的人。他们不是集邮疯子,不是把邻居的狗毒死的疯子,而是一些生活方式很另类的人。

别忘了,UNIX最初的主要发展是在六十年代和七十年代,我当时正在祖父公寓里的一个洗衣筐子里睡觉。当时正是美国嬉皮士的时代,那是一个了各种理想的 时代。革命、解放、自由爱情……于是UNIX的相对开放性对这类人就特别有吸引力,尽管在当时它还缺乏商业上的价值。

大概是 1991年前后,当时拉尔斯·沃兹尼亚斯(Lars Wizenius)拉着我去赫尔辛基理工大学参加一个集会。当时的演讲者是理查德·斯托曼(Richard Stallman)。此人是自由软件的鼓吹者。他还撰写了《自由软件宣言》和自由软件产权证书,即GPL。他首先提出的关于开放源代码的概念完全是有意 的,而并非出于偶然,和UNIX最初的开放发展理念是相吻合的。我在生活中第一次见到了典型的留着长发、蓄着长胡子的黑客形象,其代表就是理查德。这样的 人在赫尔辛基为数不多。

我当时可能没有看到眼前的光芒,但我猜他说的一些话也多少给了我一些触动。毕竟,我后来为Linux使用的就是GPL。就这样,我再一次走在了自己的前面。”

如果李纳斯没有在Minix新闻组中谈论Linux,那么这个新生的系统很可能就夭折了。一开始,他向赫尔辛基大学申请FTP服务器空间,可以让别人下 载Linux的公开版本。“Linux是我的工作名,但如果我把它作为正式名字,别人肯定会认为我是一个自大狂,不会把Linux当回事。于是我给它起了 一个很糟糕的名字:Freax。是Free(自由)+Freak(怪诞)+X组成。但负责FTP站点的阿里·莱姆克(Ari Lemmke)极不喜欢这个名字,“他倒喜欢我当时正在使用的另一个名字――Linux。我承认我并没有太坚持。但这一切都是他搞的。所以,我既可以不惭 愧地说自己不是那么以个人为中心,也不得不承认自己并非完全没有自我意识。并且我认为,这是个不错的名字。”

1992年1月,大概只有 100人左右使用Linux,但他们为Linux提供了十分关键的洗礼。这些早期的上传和评论十分重要。尤其是那些同行们为修补代码错误而上传的补丁。李 纳斯很偶然地闯进一个在线Karelia,开始着手将补丁拼凑起来。在网上,任何地方、任何人都可以得到基本的Linux文件。电子邮件使他们可以方便地 进行评论并加以改善,而Usenet新闻组则提供了一个讨论的论坛。Linux以个人的产品起步,而变成了一个百锦图,成了志向相同的黑客们的一场运动。

既使通过黑客的补丁将其不断改善,Linux内核本身也没有多大用处。Linux的腾飞必须具备其他因素,其中最关键的是自由软件基金(FSF)的 GNU计划。GNU的目标就是要编写一个完全免费的Unix版本:包括内核及所有相关的组件,可让用户自由共享并且改写软件。而Linux无疑是得来全不 费功夫。

通常一个操作系统要等待别人根据它来写相关的应用程序,而Linux却反其道而行之,李纳斯将Linux进行改写,使其与GNU现有的应用软件很好地结合起来。通过这种方式,Linux一夜之间就拥有了图形用户界面。

与敌共眠

“一个每月挣五十美元的人,他可能会为一个软件花费二百五十美元吗?如果花一点钱买非法拷贝软件,而把五个月 的工资用于吃饱肚子,我一点不觉得他不道德。这种侵权是道义上可以接受的。去追捕这种“侵权者”是不道德的,更不要说简直就是愚蠢的。就Linux而言, 谁在乎如果只将其用于个人目的时,一个人是否真正遵循了GPL呢?那些想藉此赚大钱的人们,才是真正不道德的,不管他们是在美国还是非洲,也不管程度如 何。贪欲从来就不是善的。”

李纳斯采纳了标准GNU技术许可方案,即“Copyleft”(简称GPL)。这种通用公开授权,允许用户 销售、拷贝并且改动程序,但你必须将同样的自由传递下去,而且必须让你修改后的代码也免费公开。这一举措成了Linux成功的强大力量。首先,它大大促进 了商用领域的繁荣,虽然Linux可以网上免费下载,但30美元一套的CD-ROM比自己下载更方便、更经济也更快速。同时这也大大刺激了程序员的积极 性。这种许可方式可确保他们的工作免费传播,不会被逐利之徒所利用,或锁进专有产品之中。

也就是说,GPL为Linux黑客们的网络新部落提供了一套成文的“宪法”。你可以进行开发和赢利(黑客也得吃饭),但源程序必须免费公开。

1994年3月,正式的Linux 1.0版发布,它的出现无异于网络的“自由宣言”。从此Linux用户迅速增加,Linux的核心开发小组也日渐强大。在Linux所包含的数千个文件 中,有一个名为Credits的文件,里面列出了100多名对Linux有过重要贡献的黑客,包括他们的名字、地址以及所做工作。其中的软件都是经过“优 胜劣汰”的达尔文式的选择方式所生存下来的。

Linux的方法看起来很简单:所有的黑客都可添加额外功能并完善性能。所谓的β测试也不是修补漏洞,而是集成过程。

1994年,安德森·艾文成立了Red Hat软件公司,成为最著名的Linux分销商之一。他说:“Linux和自由软件社区可以看作是真正的知识界精华。”由于这种独特的开放性,使 Linux几乎支持任何一种平台。到Linux 2.0版,已经提供了64位处理能力(而许多Unix以及Windows NT还是32位阶段),还具有对称性多重处理及更先进的网络功能。用户数已经突破千万大关,出现在120多个国家和地区,尤其在发展中国家,Linux更 是理想之选。

Linux的黑客们包括李纳斯本人,似乎对编写应用软件不感兴趣。但随着Linux市场扩展,商业公司也开始弥补这一欠缺,包括字处理、电子表格、图形软件等强劲的桌面应用软件已经纷纷涌现。

“我并没有成为一个完全的隐士,但是即使在Linux出现之后,我一如既往地不善交际。我的大多数朋友都很善于与人相处,但我不行。你可以想象一下,如 果从来没有给女人打过电话,那约会的情况会是怎样的呢?所以在那段时间里,我只有几个常到我那里敲窗子、想和我喝杯茶的朋友。我不认为有人会到处传说我正 在做一项伟大的事业、我将改变世界之类的话。我不认为有人曾经这么想过。”

“对我而言,那意味着电话一直占线,没有人能给我们打电话……后来,明信片开始从四面八方寄来。我想就是在那时,我意识到现实世界的人们确实在使用他所创造的东西。”李纳斯的妻子萨拉·托沃兹说。

最知名的程序员何以维生?

“对于任何编程的人来说,编程是世界上最有趣的事。它比下棋之类的游戏更有乐趣得多,因为它可以由你自己来制订游戏规则。而你制定什么样的规则,也就会 导出与此规则相符合的结果。然而,对于编程外行的人来说,它却似乎是世上最枯燥的事。编程给人带来的最初兴奋的原因有部分是显而易见的,那就是:通过编程 你可以支配一台计算机,而且毫无怨言。而真正使编程令人欲罢不能的是:你能让电脑做你想做的事,但是你还必须想出怎样做到的办法。

通过编程和电脑,你能够构筑一个新世界,有时其设计会是非常美妙的。而能够坐下来,盯着电脑屏幕,将一个问题彻头彻尾地贯穿思考,就需要某种特定的人。比如,需要像我这种书呆子气十足的人。”

1996年底,正当Linux如火如荼之际,一个令人震惊的消息传来:李纳斯准备离开赫尔辛基,闯荡硅谷,加盟一家不知名的计算机公司 Transmeta。许多人怀疑这会不会给发展中的Linux造成致命的伤害。但许多老资格的开发人员和商业公司都很自信,因为Linux已获得了足够的 发展动力。李纳斯为什么要到Transmeta ?“我无法告诉你,这是最高机密。”他腼腆地说,“但在合同中规定,我可以一边工作一边做Linux。”

“我认识一个瑞典人,他在Transmeta工作。他到了赫尔辛基呆了一天和我见面,那时我说:“总算可以毕业了。”,因为那时我已经几年没有好好放松 了。然后他就问我是否愿意去 Transmeta,然后我和他的老板谈。一周之后,1996年的秋天,我就坐飞机到加州来看。那时我已经在Linux上干了6年,也希望有一些别的东 西。我可不想在一根绳上吊死。我不希望Linux是我生活的全部,我希望能够找到一些本身就能激励人的东西。而且,小公司人情味比较足。还有,涉足一些世 界上没有其他人涉足的领域也让人兴奋。”

李纳斯花了整整七年时间,才获得赫尔辛基大学的硕士学位。因为他把大部分时间和精力都投进了Linux。当他完成硕士论文时,他必须面对任何一个大龄黑客都必须面临的永恒问题:在现实世界中我将何以维生?

有些人像Matt Welsh一样,继续留在学术圈中;有些人如Hannu Savolainen,销售商用Linux软件,如声卡驱动程序。而李纳斯对创办自己的公司并没有兴趣。但是,他也愉快地承认,自己也有一些黑客的欲望, 比如希望有些钱。“当然,钱不会成为我生活的主要目标。”

李纳斯做如此选择最根本的原因,还是需要一种新的挑战。他很坦诚:“如果Transmeta进展顺利,我只需工作就会很有钱,可以做自己想做的一切。”对Transmeta,他唯一透露的技术细节就是公司发展超大规模集成芯片(VLSI),当然软件很关键。

Transmeta是Dave Ditzel领头的创业公司。Dave是Sun SPARC处理器芯片开发项目的首席科学家,而SPARC是最成功的RISC芯片。Transmeta的主要投资者中就有微软的创始人之一保罗·艾伦。 Transmeta的任务是创造多媒体PC的新引擎。

促使李纳斯来到硅谷的原因不仅仅是Transmeta的劝诱,还有他刚刚降世的女 儿:Patrica Miranda,生于1996年12月。女儿的到来促使他想改变一下与Linux的长期关系。这位IT业的道士已经创造了丰富多彩的Linux 2.0,而今他又专心致志于他的另一项创造——Linus 2.0(他的女儿,见下图),我们又怎能埋怨他呢?

无疑,快到而立之年的李 纳斯已经为人类创造了一部恢弘的史诗。他本人也成了地球上最知名的程序员,互联网上真正的名人。某搜索引擎的结果显示:Sun公司CEO Scott McNealy有7192条相关信息,Oracle老板拉里·埃里森为8580条,明星汤姆·克鲁斯为16604条,而李纳斯·托沃兹则高达20419 条。

敌人真实的心态

“Linux所取得的许多成功,其实可以归结为我的缺点所致:1、我很懒散。2、我喜欢授权给其他人。黑 客们,不,程序员们,把在Linux和其他开放源代码的项目上工和放在比睡觉、锻炼身体、小圈子聚会,以及,有时是性生活更优先的地位。因为他们喜欢编 程,更因为他们乐于成为一个全球协作努力的活动的一部分――Linux是世界上最大的协作项目,这一努力将给所有喜欢它的人带来最好最美的技术。这种努力 是如此率真,又是如此有趣。”

Linux代表着网络时代新形式的开放知识产权形态,将从根基上颠覆以Windows为代表的封闭式软件 产权的传统商业模式。目前,Linux已拥有了许多世界一流的企业用户和团体用户,其中包括NASA、迪斯尼、洛克希德、通用电气、波音、Ernst &Young、UPS、IRS、Nasdaq,以及多家美国一流的大学机构等。

比尔·盖茨公开表示,他根本没把Linux放在眼里,他 预测Linux只会起一些有限的作用。但是,1998年11月,微软秘密备忘录《鬼节前夕》被揭露,微软对Linux的真实认识引起了极大反响。因为报告 高度评价了Linux的市场份额、性能和可靠性,指出:“Linux代表的是一种最优秀的UNIX系统,被广泛地应用在关键业务领域,由于其开放特 性,Linux将超过其它的操作系统。”“在人们转移至Linux后,他们会发现他们所需要的几乎所有应用程序都已被免费提供了,包括Web服务器、 POP客户、邮件服务器和文本编辑器等等。”“Linux在个人设置、可用性、可靠性、扩展性和性能表现方面均超过了Windows NT。”

报告承认:以Linux为代表的自由软件在短期上,已经对微软的收入构成威胁。而长期来说,这种自由交流思想的开发模式将极大地打击微软。

几年前,微软还在嘲笑自由软件。但如今,他们再也不能漠视这场迅速蔓延的民间运动。1993年,互联网兴起,微软首席技术官梅尔沃德半开玩笑地说:“我 们的主营业务软件到了末日,将来会暴尸于信息高速公路旁。”没想到,这个玩笑越来越成为真实。最近,这位微软帝国的“军师”突然宣布离开公司休长假。他对 一位媒体朋友的一番话很有意味,他说,未来的微软必须改变商业模式,微软不能再靠卖软件产品生存,而应该成为“应用软件服务供应商”(ASP),靠服务谋 生。但对垄断者来说,这种转变是极端痛苦的,而且能否平安转变,这位软件业的“诸葛亮”也无从把握,不敢下言。

微软总裁鲍尔默也表示, 不久微软也可能被迫公开Windows的源代码。微软是很现实,也是反应很快的公司,它介入自由软件也只是时间问题。如果微软被迫拥抱自由软件,对消费 者、对产业有益,不就是一件好事吗?但是可以肯定,如果不是迫不得已,它决不会主动放弃封闭的垄断模式。

李纳斯是自由软件未来的定心丸。

当人人都崇拜的盖茨住在他豪华的华盛顿州西雅图郊区的湖滨行宫里时,李纳斯和他的妻子以及他们蹒跚学步的女儿们却挤在圣克拉拉一栋两层楼的公寓套房里。

这位平常的芬兰人,简单而强大的Linux操作系统的创造者,超越了盖茨的神话。也有传闻说盖茨是一个卓越的程序员,但李纳斯是货真价实的高手。还在大 学里时他就完成了一个货真价实的操作系统。年轻时的盖茨把拷贝他自己平庸的程序的程序员同行称为“贼”,而慷慨的李纳斯把他的杰作与全世界共享。

多年来,在残酷的商业世界里,微软一一摆平诸多强大的对手。但是,这股完全来自民间的力量却让微软无所适从。因为,所有的原有商业规则都不起作用,微软 的市场权力突然失效。看看李纳斯·托沃兹本人,一个典型的软件工程师,语言平淡,直来直去。既没有乔布斯能言善辩的个人魅力,也没有鲍尔默激情澎湃的煽动 能力。他的讲演总像软件代码一样缺少修饰,缺乏激情和美感,还夹杂着许多生僻的技术术语。但是他的实在,他的沉稳,却能让每一位见到李纳斯的人相信:自由 软件蕴含着永恒的生命力,而且会不断进步。他是Linux未来前进方向的定心丸。

Linux就像《卡勒瓦拉》一样,由最初的约 10000行程序经过全球网络上数不清的编程人员的不断添加,目前的规模已达100万行左右;由李纳斯本人所控制的主要版本现已达到2.2版,而由各家商 业软件公司所自行开发的扩散版本更是不计其数。如何对这种开发模式进行有效地控制和管理、减少软件本身不必要的膨胀,确实是决定Linux未来发展的一个 关键性问题。

对如日中天的Linux来说,再没有比对手的褒扬和关注更高的鼓励了。李纳斯本人则不无揶揄地说:“我根本没有打算威胁微 软,因为我根本没有把微软视为真正的对手。尤其没有把Windows视为对手——因为Linux和Windows的目标完全不一样。至于说到 Windows NT,我曾经对它发生过兴趣,但是我越深入进去,就越发现它不过是一个带有较稳定的内核的传统的 Windows而已。我从中找不到任何技术上令人感兴趣的东西。依我看,微软做得更多的是怎么去挣钱,而不是去制作一个更好的操作系统。”

1999年3月3日,李纳斯在LinuxWorld的主题发言中向广大Linux程序员们呼吁,不必努力让Linux与各种商业版本的Unix相竞争, 而应该努力让Linux更为好用,使之进入桌面PC与PDA。“成为未来这个行星上最重要的操作系统。”李纳斯的发言得到了与会者的热烈欢迎。

对于Linux的未来,李纳斯也充满信心:“Linux一直就是最棒的。我对Linux的未来确实一点儿都不担心,因为从技术方面看,Linux肯定会越变越好;而从非技术方面看,我个人也看不出有什么担忧的。”

“资源共享,服务收费”,摈弃原始的不合理规则,添加新的互联网精神,使软件业真正走向以服务为中心的高级阶段,真正与高境界的知识经济相符合。这就是自由软件所指引的广阔而光明的未来之路。

乐者为王

戴着眼镜,语音轻柔,容易接近,对自己的才能和成就充满自豪,而且十分幽默。他从前是出名地逮什么吃什么,现在则对寿司情有独钟。由于编程太多,他的肚子已经有点儿凸,不过他的声音和他顽童般的笑容里远没有失去芬兰特色的那种轻快。

李纳斯看来是一个平民主义者,他希望打破垄断性软件定价的思想方式,也反映在他的其他口味上。比如,他不买精装书,因为他相信精装书卖不太好,所以定价 一定偏贵。同样,他更喜欢好莱坞的娱乐片,而不是欧洲的高品位艺术电影。他的父亲在电台工作,他的母亲翻译报纸新闻,叔叔为芬兰电视台工作,祖父是报纸记 者,所以他理解新闻媒体,而且似乎也对于自己越来越出名自得其乐。

“即使是那些无法想象世界上有人做事会出于兴趣的人--那种人是挺可 悲的,但也是有这样的人,我也可以向他们解释:10年之后Linux要是真的一帆风顺,我就要风得风,要雨得雨了,就象在银行存钱一样。这不是我的目的, 但可以这样告诉那些除此之外就无法理解的人。我认为自己是一个艺术家,在做自己乐意做的事情。而且我也不用活得特别惨,因为程序员的待遇并不差。”

Transmeta公司位于圣克拉拉一个匿名的写字楼群内,当李纳斯从公司出来时,手里拿着一罐拉开盖的可乐,穿着软件程序员的典型服装:牛仔裤,T 恤,一成不变的凉鞋和袜子。当我问他穿凉鞋着袜子是不是标准的程序员工装时,他理由充分地解释说,在他从未见到任何程序员之前他就喜欢把袜子和凉鞋配在一 起了。他说:“这肯定是关于程序员的自然法则。”

记者问出了第一个问题:“你家里人都是搞技术的吗?”

“不是,他们基本上是新闻记者,”他答道,接着又说:“所以我知道你们都是一些坏蛋。”

“噢,难道你是从一堆坏蛋是钻出来的吗?”记者也不是吃素的。

这个世界级的程序编制员抑头大笑,不料将嘴里的一口可乐全喷在了摄影兼司机的后脖子上,李纳斯的脸不好意思地红起来。

记者问他,如果见到比尔·盖茨想说些什么,他却说连与后者见一下的欲望都没有。“在我们俩之间没有什么关系可言,”他说,“他所做的事是世界上最优秀 的,但我却丝毫不感兴趣。我所做的事在世界上也可能是最优秀的,他也不感兴趣。我对他经商提不出任何建议,他对我的技术也提不出任何看法。”

“我们人类被这三种事物所驱使――对于人类以外的其他生命行为也是如此。这一次序是:生存;社会交往;寻找乐趣。它也是进化的次序。这就是我为什么选择了“Just for Fun”作为自传书名的原因。

因为我们曾经所做的一切事情,似乎最终都是为了我们自己的乐趣。”

Linux系统内核代码特色

1。缩进

8个字符的长度设置为缩进的长度。这样使得你的代码更加容易阅读,并且提醒你不要nest得过深。

2。断开长的行以及长的字符串

要记住我们的代码会被屏幕只有24个字符长度的终端阅读。

3。放置大括号

这方面我们遵从C程序员的老祖宗——Kernighan and Ritchie的风格。

if (x is true) {

we do y

}

do {

body of do-loop

} while (condition);

if (x == y) {

..

} else if (x > y) {

...

} else {

....

}

定义函数时是个例外,我们这样写

int function(int x)

{

body of function

}

采用这种方式的另外一个好处是,节省空间。我们不需要为单个的括号而占用一行的空间,要知道有些人会使用很小屏幕的终端观看代码,比如PDA用户。

4。命名规则

全局的变量或函数采用描述性的名字,务尽其详。而局部函数采用缩略方式加以命名。

匈牙利命名法不被推荐。

5。函数

函数的一个推荐风格是写得短小精悍,不要超过160x24这样的长度。如果你的函数特别长,你要尽可能得断开它,使它的部分功能放置在别的函数里。如果对性能要求特别明显,那么可以把分出去的函数设置为inline。

6。宏,枚举

最好都为大写,但是宏函数例外。

7。不要滥用inline

inline函数的原则是这个函数不超过三行代码,其中的例外就是函数参数中有可以在编译时就确定的常数,而你知道因为这个常数,编译器能够加以优化从而减少函数的代码。

该规范在php程序编写时,可以借鉴,参看这里 从linux kernel coding style看php代码规范

从linux kernel coding style看php代码规范

linux内核的编码是一种极端情况。

需要清晰明朗以供全世界的开发者学习、修改,对代码的质量要求较高。

相信linus大神在长期接触各种各式代码后脾气会变得更暴躁,就比如前段时间在某论坛痛斥C++。。。

节选,去除不适合PHP程序员阅读的部分。

如果你开发PHP程序的核心代码,比如框架,尤其建议好好思考。

虽然,它和一些权威的代码规范比如discuz和zend的有所冲突,但是依然能从中受益。

linux kernel coding style (针对PHPer作了节选)

linux kernel coding style的中文译者:

中文版维护者: 张乐 Zhang Le

中文版翻译者: 张乐 Zhang Le

中文版校译者: 王聪 Wang Cong

wheelz

管旭东 Xudong Guan

Li Zefan

Wang Chen

第一章:缩进

制表符是8个字符,所以缩进也是8个字符。有些异端运动试图将缩进变为4(乃至2)个字符深,这几乎相当于尝试将圆周率的值定义为3。

理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕连续看了20小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。

现在,有些人会抱怨8个字符的缩进会使代码向右边移动的太远,在80个字符的终端屏幕上就很难读这样的代码。这个问题的答案是,如果你需要3级以上的缩进,不管用何种方式你的代码已经有问题了,应该修正你的程序。

在switch语句中消除多级缩进的首选的方式是让“switch”和从属于它的“case”标签对齐于同一列,而不要“两次缩进”“case”标签。比如:

C++代码

switch (suffix) {

case 'G':

case 'g':

mem <<= 30;

break;

case 'M':

case 'm':

mem <<= 20;

break;

case 'K':

case 'k':

mem <<= 10;

/* fall through */

default:

break;

}
  不要把多个语句放在一行里,除非你有什么东西要隐藏:

  C++代码

  if (condition) do_this;

  do_something_everytime;

  也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表达式。

  除了注释、文档和Kconfig之外,不要使用空格来缩进,前面的例子是例外,是有意为之。

  选用一个好的编辑器,不要在行尾留空格。

  第二章:把长的行和字符串打散

  代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。

  每一行的长度的限制是80列,我们强烈建议您遵守这个惯例。

  长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句,而且放置的位置也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。

  C++代码

  void fun(int a, int b, int c)

  {

  if (condition)

  printk(KERN_WARNING "Warning this is a long "

  "3 parameters a: %u b: %u "

  "c: %u \n", a, b, c);

  else

  next_statement;

  }

  第三章:大括号和空格的放置

  C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放置策略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie展示给我们的,是把起始大括号放在行尾,而把结束大括号放在行首,所以:

  C++代码

  if (x is true) {

  we do y

  }

  这适用于所有的非函数语句块(if、switch、for、while、do)。比如:

  C++代码

  switch (action) {

  case KOBJ_ADD:

  return "add";

  case KOBJ_REMOVE:

  return "remove";

  case KOBJ_CHANGE:

  return "change";

  default:

  return NULL;

  }

  不过,有一个例外,那就是函数:函数的起始大括号放置于下一行的开头,所以:

  C++代码

  int function(int x)

  {

  body of function

  }

  全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道(a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函数都是特殊的(在C语言中,函数是不能嵌套的)。

  注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是do语句中的“while”或者if语句中的“else”,像这样:

  C++代码

  do {

  body of do-loop

  } while (condition);

  和

  C++代码

  if (x == y) {

  ..

  } else if (x > y) {

  ...

  } else {

  ....

  }

  理由:K&R。

  也请注意这种大括号的放置方式也能使空(或者差不多空的)行的数量最小化,同时不失可读性。因此,由于你的屏幕上的新行是不可再生资源(想想25行的终端屏幕),你将会有更多的空行来放置注释。

  当只有一个单独的语句的时候,不用加不必要的大括号。

  C++代码

  if (condition)

  action();

  这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大括号。

  C++代码

  if (condition) {

  do_this();

  do_that();

  } else {

  otherwise();

  }

  3.1:空格

  Linux内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__,这些关键字某些程度上看起来更像函数(它们在Linux里也常常伴随小括号而使用,尽管在C语言里这样的小括号不是必需的,就像“struct fileinfo info”声明过后的“sizeof info”)。

  所以在这些关键字之后放一个空格:

  if, switch, case, for, do, while

  但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如,

  C++代码

  s = sizeof(struct file);

  不要在小括号里的表达式两侧加空格。这是一个反例:

  C++代码

  s = sizeof( struct file );

  当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之靠近变量名或者函

  数名,而不是靠近类型名。例子:

  C++代码

  char *linux_banner;

  unsigned long long memparse(char *ptr, char **retptr);

  char *match_strdup(substring_t *s);

  在大多数二元和三元操作符两侧使用一个空格,例如下面所有这些操作符:

  C++代码

  = + - < > * / % | & ^ <= >= == != ? :

  但是一元操作符后不要加空格:

  C++代码

  & * + - ~ ! sizeof typeof alignof __attribute__ defined

  后缀自加和自减一元操作符前不加空格:

  ++ --

  前缀自加和自减一元操作符后不加空格:

  ++ --

  “.”和“->”结构体成员操作符前后不加空格。

  不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器就不会移除已经加入的空白,就像你故意留下一个只有空白的行。包含行尾空白的行就这样产生了。

  当git发现补丁包含了行尾空白的时候会警告你,并且可以应你的要求去掉行尾空白;不过如果你是正在打一系列补丁,这样做会导致后面的补丁失败,因为你改变了补丁的上下文。

  第四章:命名

  C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal程序员不同,C程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C程序员会称那个变量为“tmp”,这样写起来会更容易,而且至少不会令其难于理解。

  不过,虽然混用大小写的名字是不提倡使用的,但是全局变量还是需要一个具描述性的名字。称一个全局函数为“foo”是一个难以饶恕的错误。

  全局变量(只有当你真正需要它们的时候再用它)需要有一个具描述性的名字,就像全局函数。如果你有一个可以计算活动用户数量的函数,你应该叫它“count_active_users()”或者类似的名字,你不应该叫它“cntuser()”。

  在函数名中包含函数类型(所谓的匈牙利命名法)是脑子出了问题——编译器知道那些类型而且能够检查那些类型,这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。

  本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器,它应该被称为“i”。叫它“loop_counter”并无益处,如果它没有被误解的可能的话。类似的,“tmp”可以用来称呼任意类型的临时变量。

  如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综合症。请看第六章(函数)。

  第六章:函数

  函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完(我们都知道ISO/ANSI屏幕大小是80x24),只做一件事情,而且把它做好。

  一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理论上很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很小的事情,这样的函数尽管很长,但也是可以的。

  不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能甚至搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。使用辅助函数,并为之取个具描述性的名字。

  函数的另外一个衡量标准是本地变量的数量。此数量不应超过5-10个,否则你的函数就有问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松的同时跟踪7个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你2个星期前做过的事情。

  在源文件里,使用空行隔开不同的函数。

  第八章:注释

  注释是好的,不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的:更好

  的做法是让别人一看你的代码就可以明白,解释写的很差的代码是浪费时间。

  一般的,你想要你的注释告诉别人你的代码做了什么,而不是怎么做的。也请你不要把注释

  放在一个函数体内部:如果函数复杂到你需要独立的注释其中的一部分,你很可能需要回到

  第六章看一看。你可以做一些小注释来注明或警告某些很聪明(或者槽糕)的做法,但不要

  加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,也可以加上它做这

  些事情的原因。

  当注释内核API函数时,请使用kernel-doc格式。请看

  Documentation/kernel-doc-nano-HOWTO.txt 和 scripts/kernel-doc 以获得详细信息。

  Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ...”注释。

  长(多行)的首选注释风格是:

  C++代码

  /*

  * This is the preferred style for multi-line

  * comments in the Linux kernel source code.

  * Please use it consistently.

  *

  * Description: A column of asterisks on the left side,

  * with beginning and ending almost-blank lines.

  */

  注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只

  声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段

  小注释来解释它们的用途了。

  对于PHPER来讲,最好遵循PHPDOC风格的注释。

  第九章:你已经把事情弄糟了

  这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能

  自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们

  想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不

  会创造出一个好程序)(译注:请参考Infinite Monkey Theorem)(对于PHPer,可能就是zend studio、eclipse之类的自动格式化工具)

  所以你要么放弃GNU emacs,要么改变它让它使用更合理的设定。

  第十二章:宏,枚举和RTL

  用于定义常量的宏的名字及枚举里的标签需要大写。

  C++代码

  #define CONSTANT 0x12345

  宏的名字请用大写字母,不过形如函数的宏的名字可以用小写字母。

  。。。

  第十三章:打印内核消息

  内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要

  用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、明了、无

  歧义。

  内核信息不必以句号(译注:英文句号,即点)结束。

  写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里

  就会成为极大的帮助。

  (也就是说,默认地,它们不应该被包含在内)。(对于PHPer也是同样)

  第十八章:编辑器模式行和其他需要罗嗦的事情

  有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs

  能够解释被标记成这样的行:

  -*- mode: c -*-

  或者这样的:

  /*

  Local Variables:

  compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"

  End:

  */

  Vim能够解释这样的标记:

  /* vim:set sw=8 noet */

  这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模

  式,或者使用其他可以产生正确的缩进的巧妙方法。

  不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应

  该覆盖别人的配置。

  简而言之,8个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的

  时候可以给你警告。留心这个警告。

User-agent 字串史(客户端操作系统浏览器识别)

较古的浏览器
1993年,NCSA 发布了首款 web 浏览器 Mosaic。它的 user-agent 字串非常简洁:

Mosaic/0.9
虽然当时由于它对操作系统和平台的依赖性,但是基本格式还是很简单明了。在文本中,斜杠前面是产品名称(可能会显示为 NCSA Mosaic 或是其他类似的字),斜杠后面是产品版本号。

Netscape Communications 开发了 web 浏览器 Mozilla(当时号称“Mosaic 杀手”)。他们首款公开发行版本: Netscape Navigator 2 的user-agent 字串具有如下格式:

Mozilla/Version [Language] (Platform; Encryption)
Netscape 按之前的做法在 user-agent 字串的前半部分使用了产品名称和产品版本,但在后面增加了下列信息:

Language - 表示应用程序用的是哪个语言
Platform - 表示应用程序是在什么操作系统和/或平台中运行
Encryption - 表示应用程序包含了什么安全加密类型。其中的值可能是U(128位加密)、I(40位加密)、N(没加密)。
Netscape Navigator 2 的 user-agent 字串的示例:

Mozilla/2.02 [fr] (WinNT; I)
上面的字串指: Netscape Navigator 2.02 、法语 、Windows NT 、40位加密。在当时,通过 user-agent 字串中的产品名称,可以正确判断使用的是哪个 web 浏览器。

Netscape Navigator 3 、Internet Explorer 3
1996年,Netscape Navigator 3 发布,它远远超过 Mosaic 成为当时最流行的 web 浏览器。而 user-agent 字串只有些小的变化:去掉了语言部分,多了个放操作系统或CPU的可选信息。格式如下:

Mozilla/Version (Platform; Encryption [; OS-or-CPU description])
在 Windows 系统中 Netscape Navigator 3 的 user-agent 字串的示例:

Mozilla/3.0 (Win95; U)
上面的字串指:Netscape Navigator 3 、Windows 95 、128 位加密。在 Windows 系统中,字串里面不会显示 OS 或 CPU 的信息。

Netscape Navigator 3 发布不久,微软公布了它的首款 web 浏览器: IE 3 1,但是 Netscape 是当时首选浏览器,大多数服务器在加载页面前都会检查 user-agent 是否为该款浏览器。IE 如果不兼容Netscape user-agent 字串,使用 IE 的用户就根本打不开这些页面,于是造就了如下格式:

Mozilla/2.0 (compatible; MSIE Version; Operating System)
在 Windows 95 中 IE 3.02 的 user-agent 字串的示例:

Mozilla/2.0 (compatible; MSIE 3.02; Windows 95)
由于当时的浏览器嗅探只查 user-agent 字串中的产品名称部分,结果 IE 摇身一变被识别成了 Mozilla,伪装成 Netscape Navigator。这个做法引发了对浏览器识别的争论。从此以后,浏览器真正的版本埋没在了字串的中间。

Netscape Communicator 4 、Internet Explorer 4至8
1997年8月,Netscape Communicator 4 发布(发布的名称中 Navigator 换成了 Communicator),它的 user-agent 字串格式与 3 版本一致。Windows 98 中 4 版本的 user-agent 字串如下:

Mozilla/4.0 (Win98; I)
Netscape 浏览器在更新时,版本也相应增加。4.79 版本的 user-agent 字串如下:

Mozilla/4.79 (Win98; I)
微软发布 IE 4 时,user-agent 字串更新了版本,格式如下:

Mozilla/4.0 (compatible; MSIE Version; Operating System)
在 Windows 98 中 IE 4 的 user-agent 字串的示例:

Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)
可以看出,Mozilla 的版本与 IE 实际的版本一致,这样就可以识别第4代浏览器了。但遗憾的是,不久 IE 4.5 马上就发布了(只在 Mac 平台),虽然 Mozilla 版本仍是 4,但是 IE 的版本改成如下:

Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)
此后,IE 的版本一直到 7 都沿用了这个模式。

而 IE 8 的 user-agent 字串添加了呈现引擎(rendering engine)版本:

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
新增的呈现引擎非常重要!这样 IE8 以 MSIE 7.0 兼容模式运行时,Trident 版本保持不变,而原先 IE7 的 user-agent 字串不包括 Trident 版本。这样可以区分 IE7 与 IE8 运行的兼容模式。

注意:别指望能从 Mozilla 版本中得到什么靠谱的信息。

Gecko
Gecko 是 Firefox 的呈现引擎。Gecko 首次开发是作为 Mozilla 浏览器 Netscape 6 的一部分。Netscape 6 的 user-agent 字串的结构是面向未来的,新版本反应出从 4.x 版本的简单变得较为复杂,它的格式如下:

Mozilla/MozillaVersion (Platform; Encryption; OS-or-CPU; Language; PrereleaseVersion)Gecko/GeckoVersion ApplicationProduct/ApplicationProductVersion
为了更好的理解上面的 Gecko user-agent 字串格式,下面来看看各种从基于 Gecko 浏览器中取得的字串。

在 Windows XP 中的 Netscape 6.21:

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4) Gecko/20011128 Netscape6/6.2.1
在 Linux 中的 SeaMonkey 1.1a:

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1b2) Gecko/20060823 SeaMonkey/1.1a
在 Windows XP 中的 Firefox 2.0.0.11 :

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
Mac OS X 中的 Camino 1.5.1:

Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1
上面都是基于 Gecko 的浏览器所取得的 user-agent 字串,区别只是版本有所不同。Mozilla 版本 5.0 是自从首款基于 Gecko 发布后就一直不变,而且以后有可能也不会变2。

WebKit
2003年,Apple 宣布发布首款他们自主开发的 web 浏览器:Safari。它的呈现引擎叫 WebKit。它是 Linux 中的 web 浏览器 Konqueror 呈现引擎 KHTML 的一个分支,几年后,WebKit 的开源吸引了呈现引擎的开发人员。

这款新浏览器和呈现引擎的开发人员也遇到了曾经 IE 3.0 类似的问题:怎样才能溶入主流而不被踢出局?答案是:在 user-agent 字串中放详尽的信息,以便骗取网站的信任使它与其它流行的浏览器兼容。user-agent 字串格式如下:

Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Safari/SafariVersion
下面是示例:

Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (KHTML, like Gecko) Safari/125.1
这又是个挺长的 user-agent 字串,其中包括的信息既有 Apple WebKit 的版本,也有 Safari 的版本。凡是基于 WebKit 的浏览器都将自己伪装成了 Mozilla 5.0,与基于 Gecko 浏览器完全一样。但 Safari 的版本是浏览器的构建版本号(build number)。Safari 1.25 在 user-agent 字串中号为 125.1(如上所示)。Safari 版本 3 的 user-agent 字串包括了实际的 Safari 版本:

Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5
其中的“(KHTML, like Gecko)”在 Safari 1.0 预览版本中就有了,这字串部分是最耐人寻味又饱受诟病。Apple 的野心是为了让开发人员把 Safari 当成 Gecko,所以采取了当初微软 IE user-agent 的类似做法:Safari 是兼容 Mozilla 的,否则 Safari 用户会认为用的浏览器不受支持。

而其它基于 WebKit 的浏览器与 Safari 不同的是,没有上面说的这个情况,所以检测断定浏览器是否基于 WebKit 比看有没有明确标 Safari 更有用。

Konqueror
Konqueror 是款在 KDE Linux 桌面环境中的浏览器,基于 KHTML 开源呈现引擎。它只发布了在 Linux 的版本,但是拥有活跃的用户群。为了兼容性最大化,user-agent 字串的格式也紧跟 IE 的后尘:

Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU)
Konqueror 3.2 为了与 WebKit user-agent 字串变化保持一致,它将 KHTML 作为它的标识:

Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU) KHTML/KHTMLVersion (like Gecko)
如下所示:

Mozilla/5.0 (compatible; Konqueror/3.5; SunOS) KHTML/3.5.0 (like Gecko)
Konqueror 和 KHTML 的版本号比较一致,唯一的区别就是下点处不同,比如Konquerer 3.5、KHTML 3.5.1。

Chrome
Google Chrome 浏览器以 WebKit 作为呈现引擎,JavaScript 引擎却用了另一种。最初发布的版本是 0.2,它的 user-agent 字串格式是在 webKit 信息的基础上又增加了如下:

Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Chrome/ChromeVersion Safari/SafariVersion
Chrome 0.2 user-agent 信息的示例如下:

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13
虽我不敢完全保证,但很可能 WebKit 版本和 Safari 版本总会保持同步。

Opera
Opera 浏览器默认 user-agent 字串是现代浏览器中最合理的--正确的标识了它自己及其版本。 在 Opera 8.0 前,它的 user-agent 字串格式如下:

Opera/Version (OS-or-CPU; Encryption) [Language]
在 Windows XP 中 Opera 7.54 user-agent 字串示例:

Opera/7.54 (Windows NT 5.1; U) [en]
Opera 8 user-agent 字串的语言部分移到了括号内。

Opera/Version (OS-or-CPU; Encryption; Language)
在 Windows XP 中 Opera 8 user-agent 字串示例:

Opera/8.0 (Windows NT 5.1; U; en)
当时 Opera 做为主流浏览器之一,它的 user-agent 字串是唯一使用产品名称和版本完全真实的标识了它自己。但是由于大量的浏览器嗅探代码在 Internet 上像蝗虫飞过般只吃标 Mozilla 产品名的 user-agent 字串,造成了 Opera 的 user-agent 字串发生了完全的改变。

Opera 9 user-agent 字串有两种修改的方式:一种方式是将自己标识为 Firefox 或 IE 浏览器。在这种方式下,user-agent 字串与 Firefox 或 IE 的几乎一样,只不过末尾附加了“Opera”及版本号。如下所示:

Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50
前一字串将 Opera 9.5 标识为 Firefox 2。后一字串将 Opera 9.5 标识为 IE 6,在两个字串中都带有 Opera 版本信息。虽然这种方式是作为 Firefox 或 IE 打开的,但也能识别出 Opera。另一种方法则是浏览器 user-agent 字串标识伪装成 Firefox 或 IE,同时也找不到“Opera”字串及其版本信息。这样从字面上去区分 Opera 浏览器便成了“不可能完成的任务”。3

结论
user-agent 字串史可以说明曾对 user-agent 嗅探说不的原因:IE 想要将自己识别为 Netscape 4,Konqueror 和 WebKit 想要识别为 Firefox,Chrome 想要识别为 Safari。这样使得除 Opera 外所有浏览器的 user-agent 嗅探区别很小,想要从一堆茫茫浏览器海洋中找出有用的标识太少了。关于嗅探要记住:一款浏览器与其它浏览器是兼容的,这样造成了不能完全准确的断定是哪款浏览器。

比如说 Chrome ,它声称任何可以在 Safari 3 访问的网站 Chrome 也都可以访问,但是对检测 Chrome 没有一点用。为了浏览器的兼容--这便是这个声明的理由。

(完)

译注1:IE 3 不是微软首款浏览器,请参考 wiki 的 Timeline of web browsers。

译注2:这个是原作者的想法,译者不敢保证。

译注3:Opera 10 的 user-agent 字串大家自己去看吧。

PHP_带smtp验证的发邮件函数

#echo send_mail($_POST["email"],$tosubject,$_POST["errortext"]);
echo send_mail('someone@126.com','only a test mail for test php mail function','一封垃圾邮件');
echo time();

function send_mail($to, $subject = 'No subject', $body) {
        $loc_host = "mail.server";            //发信计算机名,可随意
        $smtp_acc = "smp@163.com"; //Smtp认证的用户名
        $smtp_pass="pwdpwd";          //Smtp认证的密码,一般等同pop3密码
        $smtp_host="smtp.163.com";    //SMTP服务器地址,类似 smtp.tom.com
        $from="smp@163.com";       //发信人Email地址,你的发信信箱地址
    $deliver=$smtp_acc; //回复到指定邮箱
    $headers = "Content-Type: text/plain; charset=\"gb2312\"\r\nContent-Transfer-Encoding: base64";
    $lb="\r\n";                    //linebreak    
        $hdr = explode($lb,$headers);     //解析后的hdr
    if($body) {$bdy = preg_replace("/^\./","..",explode($lb,$body));}//解析后的Body

        $smtp = array(
      //1、EHLO,期待返回220或者250
      array("EHLO ".$loc_host.$lb,"220,250","HELO error: "),
      //2、发送Auth Login,期待返回334
      array("AUTH LOGIN".$lb,"334","AUTH error:"),
      //3、发送经过Base64编码的用户名,期待返回334
      array(base64_encode($smtp_acc).$lb,"334","AUTHENTIFICATION error : "),
      //4、发送经过Base64编码的密码,期待返回235
      array(base64_encode($smtp_pass).$lb,"235","AUTHENTIFICATION error : "));
      //5、发送Mail From,期待返回250
      $smtp[] = array("MAIL FROM: <".$from.">".$lb,"250","MAIL FROM error: ");
      //6、发送Rcpt To。期待返回250
      $smtp[] = array("RCPT TO: <".$to.">".$lb,"250","RCPT TO error: ");
      //7、发送DATA,期待返回354
      $smtp[] = array("DATA".$lb,"354","DATA error: ");
      //8.0、发送From
      $smtp[] = array("From: ".$deliver.$lb,"","");
      //8.2、发送To
      $smtp[] = array("To: ".$to.$lb,"","");
      //8.1、发送标题
      $smtp[] = array("Subject: ".$subject.$lb,"","");
      //8.3、发送其他Header内容
      foreach($hdr as $h) {$smtp[] = array($h.$lb,"","");}
      //8.4、发送一个空行,结束Header发送
      $smtp[] = array($lb,"","");
      //8.5、发送信件主体
      if($bdy) {foreach($bdy as $b) {$smtp[] = array(base64_encode($b.$lb).$lb,"","");}}
      //9、发送“.”表示信件结束,期待返回250
      $smtp[] = array(".".$lb,"250","DATA(end)error: ");
      //10、发送Quit,退出,期待返回221
      $smtp[] = array("QUIT".$lb,"221","QUIT error: ");

        //打开smtp服务器端口
        $fp = @fsockopen($smtp_host, 25);
        if (!$fp) echo "<b>Error:</b> Cannot conect to ".$smtp_host."<br>";
        while($result = @fgets($fp, 1024)){if(substr($result,3,1) == " ") { break; }}
       
        $result_str="";
        //发送smtp数组中的命令/数据
        foreach($smtp as $req){
                //发送信息
                @fputs($fp, $req[0]);
                //如果需要接收服务器返回信息,则
                if($req[1]){
                        //接收信息
                        while($result = @fgets($fp, 1024)){
                                if(substr($result,3,1) == " ") { break; }
                        };
                        if (!strstr($req[1],substr($result,0,3))){
                                $result_str.=$req[2].$result."<br>";
                        }
                }
        }
        //关闭连接
        @fclose($fp);
        return $result_str;
}

MS SQL SERVER 孤立用户问题

Windows环境下,经常遇到系统Over的情况,如果你在新装了系统和SQL Server 2005后,需要把SQL Server2000数据库还原,就会出现孤立用户的问题,下文中我们将介绍具体的解决方法:

解决步骤如下:

1.首先,需要还原数据库。 feedom.net

2.在 安全性/登陆名/新建登陆名,把产生的孤立用户新建一个,密码什么都设置好。

3.最后在查询分析器中执行

exec sp_change_users_login 'update_one','没有登陆名的数据库用户','新的登陆名'

-----------

检测当前数据库的孤立用户

sp_change_users_login @Action='Report';

MS SQL server 自定义函数:获取汉字拼音首字母(音序)

转来的,很好用,要谢谢作者的

Create function [dbo].[fun_getPY]
(
    @str nvarchar(4000)
)
returns nvarchar(4000)
as
begin
declare @word nchar(1),@PY nvarchar(4000)

set @PY=''

while len(@str)>0
begin
    set @word=left(@str,1)

    --如果非汉字字符,返回原字符
    set @PY=@PY+(case when unicode(@word) between 19968 and 19968+20901
               then (
                    select top 1 PY
                    from
                    (
                     select 'A' as PY,N'驁' as word
                     union all select 'B',N'簿'
                     union all select 'C',N'錯'
                     union all select 'D',N'鵽'
                     union all select 'E',N'樲'
                     union all select 'F',N'鰒'
                     union all select 'G',N'腂'
                     union all select 'H',N'夻'
                     union all select 'J',N'攈'
                     union all select 'K',N'穒'
                     union all select 'L',N'鱳'
                     union all select 'M',N'旀'
                     union all select 'N',N'桛'
                     union all select 'O',N'漚'
                     union all select 'P',N'曝'
                     union all select 'Q',N'囕'
                     union all select 'R',N'鶸'
                     union all select 'S',N'蜶'
                     union all select 'T',N'籜'
                     union all select 'W',N'鶩'
                     union all select 'X',N'鑂'
                     union all select 'Y',N'韻'
                     union all select 'Z',N'咗'
                      ) T
                   where word>=@word collate Chinese_PRC_CS_AS_KS_WS
                   order by PY ASC
                          )
                      else @word
                 end)
    set @str=right(@str,len(@str)-1)
end

return @PY

end

HTTP协议header头域

HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。
通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

通用头域
通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。下面简单介绍几个在UPnP消息中使用的通用头域。
Cache-Control头域
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下:
Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
Date头域
Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。
Pragma头域
Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache-Control:no-cache相同。

请求消息
请求消息的第一行为下面的格式:
MethodSPRequest-URISPHTTP-VersionCRLFMethod表示对于Request-URI完成的方法,这个字段是大小写敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE。方法GET和HEAD应该被所有的通用WEB服务器支持,其他所有方法的实现是可选的。GET方法取回由Request-URI标识的信息。HEAD方法也是取回由Request-URI标识的信息,只是可以在响应时,不返回消息体。POST方法可以请求服务器接收包含在请求中的实体信息,可以用于提交表单,向新闻组、BBS、邮件群组和数据库发送消息。
SP表示空格。Request-URI遵循URI格式,在此字段为星号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。CRLF表示换行回车符。请求头域允许客户端向服务器传递关于请求或者关于客户机的附加信息。请求头域可能包含下列字段Accept、Accept-Charset、Accept-Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If-Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、Proxy-Authorization、Range、Referer、User-Agent。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为实体头域处理。
典型的请求消息:
GEThttp://class/download.microtool.de:80/somedata.exe
Host:download.microtool.de
Accept:*/*
Pragma:no-cache
Cache-Control:no-cache
Referer:http://class/download.microtool.de/
User-Agent:Mozilla/4.04[en](Win95;I;Nav)
Range:bytes=554554-
上例第一行表示HTTP客户端(可能是浏览器、下载程序)通过GET方法获得指定URL下的文件。棕色的部分表示请求头域的信息,绿色的部分表示通用头部分。
Host头域
Host头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
Referer头域
Referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。
Range头域
Range头域可以请求实体的一个或者多个子范围。例如,
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。
User-Agent头域
User-Agent头域的内容包含发出请求的用户信息。

响应消息
响应消息的第一行为下面的格式:
HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF
HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。Status-Code是一个三个数字的结果代码。Reason-Phrase给Status-Code提供一个简单的文本描述。Status-Code主要用于机器自动识别,Reason-Phrase主要用于帮助用户理解。Status-Code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI进一步的信息。响应头域包含Age、Location、Proxy-Authenticate、Public、Retry-After、Server、Vary、Warning、WWW-Authenticate。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。
典型的响应消息:
HTTP/1.0200OK
Date:Mon,31Dec200104:25:57GMT
Server:Apache/1.3.14(Unix)
Content-type:text/html
Last-modified:Tue,17Apr200106:46:28GMT
Etag:"a030f020ac7c01:1e9f"
Content-length:39725426
Content-range:bytes554554-40279979/40279980
上例第一行表示HTTP服务端响应一个GET方法。棕色的部分表示响应头域的信息,绿色的部分表示通用头部分,红色的部分表示实体头域的信息。
Location响应头
Location响应头用于重定向接收者到一个新URI地址。
Server响应头
Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。

实体
请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,实体头包括Allow、Content-Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、Etag、Expires、Last-Modified、extension-header。extension-header允许客户端定义新的实体头,但是这些域可能无法未接受方识别。实体可以是一个经过编码的字节流,它的编码方式由Content-Encoding或Content-Type定义,它的长度由Content-Length或Content-Range定义。
Content-Type实体头
用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型Content-Range实体头
Content-Range实体头
用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth
例如,传送头500个字节次字段的形式:Content-Range:bytes0-499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范围,Content-Length表示实际传送的字节数。
Last-modified实体头
指定服务器上保存内容的最后修订时间。

推荐工具firefox插件:live http header,可以很方便的查看http header 还有其它的一些功能,严重推荐.