2005年05月27日

特别说明:此种改变只能用于在刚开始建站时才可,如果你中途改变的话就会出现问题。 

  也许提到MD5时大家都很熟,但你真的是这样吗?了解其是如何进行散列的实际过程吗?虽然我们一般的人是不用这样去寻根问底,要用的时候直接去下载别人已编好的程序用就得了。

     由于算法大多的人都是知道的,所以现在网上有很多破解MD5散列值的工具,但我们搞安全的完全可以发挥我们的想象力充分地调动自己的积极性,是否想过自己也重改造一个MD5的算法呢?让现在所有的破解MD5的工具下课呢?因为MD5在我们网络中实在是用得太广了,各网站要保存用户的资料,但明文保存时又怕万一被哪个攻击者攻入网站,下载了数据库,所以我们常用MD5进行散列各种重要的资料。但是现在有好多工具是可以进行简单的破解的。

      我们先来了解一下MD5这个散列算法,然后我再一个例子说明如何提高了网站的安全性。


  下边我只是简单的说明,x与y的所在空间就不作介绍了(x∈A,y∈B)。我们来看看一个散列算法一般是要满足下面三个条件之一:

  1、 H是一个单向函数。即对几乎所有的H(x)=y,已知y要求x,则在计算上是不可行的。

  2、 已知x,找x′∈A,使H(x)=H(x′)在计算上是不可能的,这也就是弱无碰撞性。

  3、 找一对x和x’, 而x≠x’,使H(x)=H(x′)在计算上也是不可行的,这也就是强无碰撞性。

  这样就称为安全保密的Hash函数。下边是对消息的散列过程:

  由上边的表大家也许看到了左边是不是要求输入一个初始向量IV,这也就是今天我说明的关键地方,这个初始向量要MD5算法中是由A、B、C、D四个缓冲区寄存器存放的,而每一个寄存器是32比特。它们的初始值是:

  a = 0×67452301

  b = 0x EFCDAB89

  c = 0x 98BADCFE

  d = 0x 10325476

  在这我们可以看到这四个16进制的值,这也可看做是一种初始的种子,如果大家对MD5的算法过程清楚的话,我们可知在这过程在主要是一些异或、求模等的运算,对每一个分组512比特消息进行处理的,而每一分组都进行4*16次的运算,所以我有个大胆的想法,只是我们把初始值进行稍微的改变的话,那不就是变成另外的MD5散列算法了吗!我们知道A、B、C、C四个值共是16进制的4*8=32位,那么我们都可计算可能被破解的概率空间,如果动得更多的话,那被破解的可能性也就越小。只要我们改变一位的话,而同时我们也不必改动算法的其它部分,从而也不会对我们的程序进行多大的变动。是不是就找到一种新的散列算法了呢,其实,对散列算法有研究的就可知,美国的信息压缩标准SHA也是与MD5有点相似(主要是指思路)。

  现在介绍了这些有关的MD5知识后,我们来看看如何修改我们网站管理程序的源码,这里我以国内有名的动网论坛DVBBS7.0说明。

  我们都知道动网论坛的用户的数据如密码,提问的问题的答案是以MD5散列的,通常攻击者就是下载了数据库来进行破解而得到管理员的密码的,默认的是放在这个路径下的:bbs\data\dvbbs7.mdb 而我们一般是采用的是修改数据库的名字,同时相应的修改一下conn.asp中的相关设置。

  现在我们的方法是你找到这个文件\inc\md5.asp。这个页面就是我们进行散列处理的程序,只是在这修改一下的话,我们就产生了自己的新MD5散列算法。然后以记事本的方式打开它,找到这个地方。

  看到了吧,a、b、c、d这四个值了吧,就是我们前边谈的哟,看你如何改了。随你的便了吧!但我建议是你最好改一位就可了,还是尽量少改吧。如你可把a = 0×67452301改为a = 0×67452300这样你就用了一个与众不同的MD5算法呢,这样,哪怕就是你的数据库被下载了,你也可以放心的用了。让他们的破解MD5的工具见鬼去吧!

  但是我要说明的是,了解MD5过程的人可能会问,你这样改变会影响操作吗?这个问题专家可能都很难把它论证。同时我给大家要说的是,MD5是征对所有的信息的,而我们这样的改变,仅仅用在一个网站上的几千个,上万个用户的话,应该是没有多大问题的,但是我们要从数学上证明它这个改变后也能满足文章开始时说的三个条件的话,确实有一定的难度,这就让读者去讨论一下吧。

如果真如学校的通知说的那样,国庆长假后的第一天将成为小吴暂时告别校园的日子。那一天,他将和其他无力缴清学费的同学一起办理休学手续。
   
与校园外的嘈杂、混乱相比,临沂师范学院显得格外干净、美丽,但刚升入大三的小吴早已无心享受这一切,他自喻就像断了线的风筝,没有了头绪和方向
    8
29日开学以来,学校连发几道催缴学费的通知改变了他的生活。他欠缴学费3600元和住宿费800元。
   
缴不起学费的学生面临清退出校
    9
16日,本报接到临沂师范学院一些贫困学生的求助信,他们由于无力支付今年的学费,正面临失学的危险。因为学校下达了一则让他们坐卧不安的通知:凡是在912日下午6时以前未缴学费和住宿费的同学,按自动退学处理,清出宿舍。
   
他们在信中说:现在的我们不能在校园里安心地读上心爱的中国青年报了,我们陷入了困境。
    9
21日,在该校7号学生宿舍楼,记者看到门上贴着的一份关于清缴住宿费的紧急通知,通知要求未缴住宿费的“02级本科,03级专本科同学可利用国庆节假期筹资,107日返校后一并上缴,截止到108日止,凡是未缴住宿费的,一律不许住宿,并清退出校
   
通知下面是一长串未缴住宿单据的学生名单。有好几位学生告诉记者,单据上包括学费和住宿费两项内容,只要一项没有缴清,代收银行就不会给单据。在他们看来,催缴住宿费就等于催缴学费。
   
记者在临沂师院采访的几天里,有院系专门召集未缴学费的贫困生开会,在会上校方明确表示:107日前必须缴清学费和住宿费,如果交不上,108日统一办理休学一年的手续。
   
在会议结束半小时后,记者找到了那间教室,还有两名学生正低声交谈,满脸愁容。在记者表明身份后,这两位大二的学生随记者先后走出教学楼,他们不愿意接受采访,担心影响学校的声誉
   
最终,他们还是向记者证实了会议内容,但心存侥幸:学校也许只是吓吓我们吧。
   
我们是以学生缴费,来维持学校的正常办学
     9
23日中午,临沂师范学院院长助理李培江在办公室接受了记者采访。他说,对于实在缴不起学费的学生,学校会保留其学籍和档案,让其休学一年,通过打工等途径筹集到学费后,再与下一届的学生一起上课。
   
记者向他提出了未缴清学费贫困学生对学校的质疑,他告诉记者,我们是以学生缴费,来维持学校的正常办学,作为财政拨款以市为主的临沂师院,市财政拨款十分有限,还不足以发放教职工工资,办学经费主要来源是学生缴纳的学费,出台这样的措施,也是没有办法的事。据该院财务处邵副处长介绍,今年市财政的拨款总额为2000多万元(记者下午从临沂市财政局证实了这一数字),而全年教职工的工资发放就需要3000多万元。
    9
月上旬,学校向未缴学费的学生及家长发出了第一封催缴学费的信件,要求他们在12日前缴清学费,然后才能注册才能有学籍,到时缴不了学费的,建议休学。912日,学校统计结果显示,在除新生以外的14万多名学生中,未缴学费的还有4300多人。
   
之后,学校又发出内容相似的第二封信,李培江估计,在107日那天,大部分学生能够缴清学费,因为在他看来,现在有部分学生是有钱故意不缴。
    
李培江指出,学校不是慈善机构,学生缴费上学是国家要求的,学校不能因为没有缴费的学生影响缴费的学生。对学生认为休学不近人情的看法,学院宣传部部长王明福认为,让缴不起学费的学生休学,从制度层面看,不近人情,但学校一直在充满感情地帮助贫困生:有的院系已经发动教职工救助贫困生,力争不让一个人失学。
   
休学压力下扭曲的生活
   
不管最后会不会被责令休学,小吴都认为学校此举很让人寒心学校太不讲情面了。这句话,小吴反复说了好几次。921日下午,学校图书馆前空旷的广场上,夕阳照在小吴身上,把他清瘦的身影拉得老长。
   
我已经横下一条心,学校真那样做的话,退学就退学。小吴叹了一口气,没办法啊,为了我上学,家里已经欠了将近两万元的债了,都已经没有地方借钱了。对小吴来说,退学很可怕,但更可怕的是,他不知道父母将会怎样面对这种残酷的打击。
   
因欠缴学费而面临失学的巨大压力,明显改变了小吴这20多天的生活轨迹。他撕毁了曾经踌躇满志写下的学习规划书,很少逃课的他经常不上课了,也不再像以前一样去图书馆自习。集体活动能躲就躲,而以前,在同学眼中,他总是一位积极的参与者。
   
现在随便什么时候去寝室找小吴,十有八九都会在。同班同学小林告诉记者。他也是一位贫困生,和小吴常常一起逃课。他害怕上课的一个理由是,有时一边上课,一边想着家里的难处,眼泪哗地就流下来了
   
睡觉,从中午12点一直到下午四五点;发呆,坐在书桌前双手托腮,盯着天花板能看上10分钟;在宿舍间串来串去,聊着无聊的话题。这就是小吴在寝室的主要生活内容。
   
最近一星期,他的睡眠质量明显下降了,上床以后常常要熬到凌晨一两点才能入睡,而早上五六点就醒来了。挺烦的,想不去想都不行
   
在小吴心中,一所理想的大学必须做到这一点:能保证贫困学生上完4年大学,学生缴学费有困难,学校要帮忙解决,而不应该三番五次的催缴,甚至以休学要挟。
   
隐藏着失学的危险
   
休学真的能解决贫困学生上学难的问题吗?学生即使在休学期内筹集到了学费,他因此而失去的又是什么?休学是否会导致部分贫困生最终离开大学校园呢?带着这些问题,记者今天采访了几位仍欠缴学费的贫困生。
   
他们一致认为,休学一年就会荒废一年时间。休学导致的损失远比我挣到的学费要多,因为失去一年的青春,是打工赚来的几千元学费弥补不了的。另一位大三学生则告诉记者:休学会打乱我的学习计划,影响考研。
   
有两位贫困生担心,休学后可能还赚不够学费。现在找活干很困难,顶多600元一个月,还不包吃住。他们认为休学根本就解决不了学费的问题,只是在拖延时间。我解决了一年的学费,然后读一年书,下一年的学费还是没有,难道要我再休学?
    
一位贫困生表示,自己不会轻易失学,休学后会想方设法重回校园,但他认为,有些人因此而失学的可能性会很大,贫困的压力会导致厌学。如果要休学,还不如在我们大一入学前就通知说没钱就别来上学了。这位贫困生认为,休学要比最初没钱来上学更痛苦

pixfirewall(config)# write terminal 6.2
Building configuration…
: Saved
:
PIX Version 6.2(1)
nameif ethernet0 outside security0
nameif ethernet1 inside security100
nameif ethernet2 intf2 security10
enable password Ujkil6aDv2yp6suI encrypted
passwd OnTrBUG1Tp0edmkr encrypted
hostname pixfirewall
domain-name cisco.com
fixup protocol ftp 21
fixup protocol http 80
fixup protocol h323 h225 1720
fixup protocol h323 ras 1718-1719
fixup protocol ils 389
fixup protocol rsh 514
fixup protocol rtsp 554
fixup protocol smtp 25
fixup protocol sqlnet 1521
fixup protocol sip 5060
fixup protocol skinny 2000
no names
!— This line allows GRE traffic from the
!— PPTP server to the client.
access-list acl-out permit gre host 209.165.201.25 host 209.165.201.5
pager lines 24
logging on
logging console debugging
logging trap debugging
interface ethernet0 auto
interface ethernet1 auto
interface ethernet2 auto shutdown
mtu outside 1500
mtu inside 1500
mtu intf2 1500
ip address outside 209.165.201.1 255.255.255.224
ip address inside 10.48.66.47 255.255.254.0
ip address intf2 127.0.0.1 255.255.255.255
ip audit info action alarm
ip audit attack action alarm
no failover
failover timeout 0:00:00
failover poll 15
failover ip address outside 0.0.0.0
failover ip address inside 0.0.0.0
failover ip address intf2 0.0.0.0
pdm history enable
arp timeout 14400
!— This allows traffic from a low security interface to
!— a high security interface.
static (inside,outside) 209.165.201.5 10.48.66.106 netmask 255.255.255.255 0 0
!— This applies the ACL to the outside interface.
access-group acl-out in interface outside
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 rpc 0:10:00
h323 0:05:00 sip 0:30:00 sip_media 0:02:00
timeout uauth 0:05:00 absolute uauth 0:04:00 inactivity
aaa-server TACACS+ protocol tacacs+ 
aaa-server RADIUS protocol radius 
aaa-server LOCAL protocol local 
no snmp-server location
no snmp-server contact
snmp-server community public
snmp-server enable traps
no floodguard enable
no sysopt route dnat
telnet timeout 5
ssh timeout 5
terminal width 80
Cryptochecksum:18bdf8e21bd72ec0533795549165ecf5
: end
[OK]

2005年05月25日

科学证明,天然水晶具有压电性(Piezoelectricity),而且天然水晶平均秒一秒可以释放出八百万次的震荡,这之间蕴藏着强大且丰沛的能量。并且,天然水晶经过地球动辄千万年以上的粹炼,长期与大自然间共振及互动,其正向磁场隐藏着巨大且无限的能量波。对于长期暴露在负向磁场的我们,佩带天然水晶有助于将自身的能量频率转为更强大的正向磁场请且释放,进而影响到我们平常的生活、工作、交友或学业的表现。
 
水晶为物理上,化学上均甚安定之材料,其压电性质(Piezoelectricity)及弹性性质使其机械振动表现于电气上时,有高Q 值、低动率,高敏锐性、高稳定性、… 等优良频率特性。因此凡是要求高度精密,稳定频率之振荡器、滤波器皆须用水晶作为振荡材料。其用途如频率合成、计数、导航、导向、传真、计算机、通信、计时、… 等其在国防军事上的用途,更见其重要性。
 
水晶Rock Crystal Quartz的最主要元素是SiO2(二氧化硅),答对了,就是Quartz(石英)。我们常把透明的石英称为水晶,其实他们是相同元素的。石英的化学成分就是二氧化硅SiO2,属六方晶系,摩式硬度为7,比重为2.66,折光率为1.54-1.55,双折射率为0.0009具玻璃光泽(玻璃则无双折射率)。而常见的石英多为块状体,但是偶尔也会有具良好且透明的结晶。各种水晶含有不同的微量金属,使各种水晶拥有其独特的颜色,紫水晶含少量铁、黄水晶含少量金砂石、粉水晶含少量钛。
 
而SiO2(二氧化硅)一般分为两种–低温石英及高温石英。水晶的生长温度约在550-600℃间,在550-573℃之间生成的属于低温石英,常见的水晶即属此类,其水晶簇柱是六角柱体(六方晶系);573-600℃之间生成的属于高温石英,玛瑙 就是常见的高温石英。
 
石英最常见的结晶类型是六角不对称尖柱状的低温石英,这是在地表温度范围所形成的石英。另有一种石英在较高的温度下结晶形成,称为高温石英,形状为对秤的六脚尖柱状。还有一种高压环境下形成的石英,通常在地下深处或天体撞击下可发现这种高温石英
 
 石英是花岗岩的主要成分,因具有较高的硬度,而且性质稳定,所以可以在风化侵蚀的过程中保留下来,因此也是砂岩的主要成分,特别是石英砂岩中,石英的含量更高。 而石英也是玻璃的主要原料,台湾西部许多地方取较纯的石英砂或自地层中取较纯的石英砂岩作为原料;东部海边则常可看到许多人捡拾白色的石英卵石做为制造玻璃的原料,这些卵石多半来自于变质岩中的石英脉.纯净无狭雌的石英也可以用作计时震荡器,如手表内的震荡器,早期取自天然石英,现在多以人工合成的方式,不仅可以控制质量,也可以量产降低成本。
 
好啦,接下来我们来看看水晶的分析
刚刚说过,水晶频率平均每一秒释放出八百万次的震荡,古时人们已知道水晶充满能量,但过去科学不发达,未能以科学方法研究水晶,到了近代两个世纪,科学起飞,人们逐渐发现水晶的物理性。在上十九世纪未,科学家已发现石英有Piezoelectricity ( 压电性 ),于石英一端施压,另一端会释出电荷。
到上世纪二十年代,科学家又发现石英有Frequency(振荡)现象,当水晶通电时,水晶会膨胀,截断电流时便收缩到原来大小;不断快速地重复供电、停电,水晶则不断的高速胀缩振荡,而振荡的频率却极为隐定。因为振荡频率高速而隐定,所以水晶便被制成芯片,是电器零件不可或缺的原材料。
而经过许多专家学者多年对水晶的深入研究,水晶被确定有五大功能:聚焦折射、储存数据、传递讯息、能源转换、能量扩大。
 
(1)   聚焦折射Focus
古时人类已发现水晶有聚焦功能,也可把光线折射,通过水晶这特点可造出凸透镜、凹透镜等。于雷射运用中,芯片和光速之合用,可使于读秒声中测出地球与月球间的距离,利用晶体的特性以可激发出高能量光束、强大、高度平行,精密者可运用于眼科手术,巨大者可运用在如「星战计划」中摧毁来袭的飞弹等等。
(2)   储存数据Storage
当有讯息通过水晶,这些信息会被水晶记下,计算机记亿体里的芯片正是有此功能。到了近代所制造出的光谱仪的镜片、棱镜等。压电下的水晶会带正、负不同电荷,这也是计算机二进制中的0与1,没错,这就是计算机的基础。一直发展至今,这种储存记忆的容量惊人,可以将大英百科全书全部的数据输入在比橡皮擦更小的体积内。
(3)   传递讯息Transfer
很多电器中的信息传递也要靠芯片,因为水晶振荡的频率隐定,用来传递讯号误差很少。由于水晶芯片的振荡极精准,且极有规律,除了可用来作电子表的时间控制外,还可以执行电算机的精密计算,更可用来作计算机与计算机间巨大讯息的传输。
(4)   能源转换Transform
水晶可把不同的能源转换成其它能源,例如把电能转成光能、热能、声能、磁能,又可把这些能源转成电能。太阳能转成电能便需靠集热芯片。可将能源型态使之转换,比如太阳能集热芯片,可将光变电、电变磁等等。声、光、电、热、磁都是能源,能源不灭,只是转换至不同型态,而水晶是最佳媒人。
(5)   能量扩大Amplify
能源通过水晶能够增强而频率不变,例如用扩音器时,电流通过石英转换成声能后(能源转换),再增强声浪(能量扩大),而且不会有走音情况出现(频率不变)。可将同频率的电子讯号同频扩大,像收音机里的晶体会接收空气中的电波,并将以扩大再转换出来,就是人们耳朵听到的声波了。而这之间的倍数何止千万倍。
 
在介绍过水晶的科学分析及验证之后,我们来看看水晶的分类。水晶的分类是五花八门,通常大致可分三类:1.Crystalline Varieties (显晶类)、2.Crypto crystalline Varieties(隐晶类)、3. Special Varieties(特别类)。
一.Crystalline Varieties(显晶类):
平时我们观赏到由多条六角形水晶柱(六方晶系)生成一簇的水晶簇,便是属于Crystalline Varieties显晶类,如白水晶、紫水晶、黄水晶、粉晶、发晶、虎眼石等皆属此类。
二.Crypto crystalline Varieties(隐晶类):
隐晶类水晶外观是一块块的,不是成六角水晶簇状,但他们却也是属六方晶系的。但我们不能以肉眼观察到他们的六角形结晶,因为结晶的体积极为细小,需以显微镜协助下才能看到六角形结晶。而此类水晶非常平滑,因为结晶之间有"水化硅石"填补。玛瑙便属于此类。
三.Special Varieties(特别类):
这类水晶和一般水晶分别很大,难以归为显晶类或隐晶类,所以归纳为特别类,例如结晶古怪嶙峋的Skeleton Crystal(骨干水晶)、水晶内有山水星像图案的Phantom Crystal(幻影水晶)等皆归纳为此类。
 
OK!大家知道水晶的大概状况之后,我们最后分析一下天然水晶和人造水晶的最大不同点。
天然水晶遍布全世界,多产自巴西及乌拉圭等南美地区,亦有产自青藏高原,他们生长在地底或洞穴深处,气压需要约地面气压的2至3倍,并且要有含饱和二氧化硅的地下水源源不绝供应,温度需在550-600℃间,经过数万百年、甚至是过千万年的时间,二氧化硅便结成水晶,等待人们去堪探发掘,这是天然水晶昂贵的原因。
但现在科技发达,而且对水晶的需求量又更加的与日俱增(在前面已经大概描述过水晶的科学功能)。所以我们就在工厂中模拟石英的生长环境,大量生产水晶切割成芯片,以满足工业用途(例如石英表、计算机中的CPU便需要芯片)。这就是人造水晶,俗称养晶。
 
原料  石英含量%  主要相关行业
石英岩  90-99  硅铁工厂、耐火砖业
石英砂(硅砂)  85-99  硅砂工厂、铸造业、玻璃业、砂纸制造业、耐火砖业
黏土  0-60  耐火砖业、瓷砖业、卫浴瓷器、日用瓷器、艺术陶瓷、蔺草加工厂、窑炉制造业
花岗岩  25-30  建筑用石材
玛瑙、水晶  >98  宝石琢磨业
 
在工厂生产的水晶生长速度相当惊人,可达到一天0.8mm,一般工业用途的3cm厚石英,大约38日便可生成,所以价值远不及天然水晶。人造水晶价值偏低,生长速度快,一块要磨成水晶球的石英,不用半年便能生成,而其它水晶链子的小珠生长时间则更短,但天然水晶却要用上数千万年的时间。所以很多奸商也把人造水晶讹称天然水晶贩卖,大家要小心啊!天然水晶在大自然中吸收了数千万年能量,这是人造水晶绝对不可比拟的,我们常常带水晶在身上改变自身的能量及磁场,但是我们绝没看过有人戴一颗CPU(中央处理器芯片组)在路上晃ㄚ晃的来改变自身的磁场吧。

2005年05月23日


  鉴于并非所有局域网的连接方式都是代理式的(实际上,几乎稍具规模的局域网都不是代理式的),所以,找到一套通过路由器端控制的方法是比较切实需要的。不少单位(如我们)都是在不同网段使用较低级别的路由器来连接网络,SOHO级别的路由器允许设置的限制规则条数均不多带来许多的困难。

  以下是我本人的方案,基本的思路是:1、常用端口封堵;2、重点服务器IP封堵;3、流入、流出数据封堵结合。

  现在的运作证明,没有人能突破这个封锁。

  一、域名过滤;

  对所有进出路由器的数据包中,包含下列域名的数据均作丢弃处理:

  QQ.COM TENCENT.COM

  二、报文过滤;

  流出过滤:(使用8条规则即可)   

  1、所有内网IP的UDP4001-4009端口发出的报文全部丢弃。 

  2、所有内网IP的8000端口发出的报文全部丢弃。 

  3、所有目标IP为218.18.95.220的报文全部丢弃。 

  4、所有目标IP为61.144.238.145的报文全部丢弃。
 
  5、所有目标IP为61.141.194.227的报文全部丢弃。 

  6、所有目标IP为218.17.209.23的报文全部丢弃。 

  7、所有目标IP为218.18.95.153的报文全部丢弃。 

  8、所有目标IP为218.18.75.171的报文全部丢弃。

  流入过滤:(使用6条规则即可) 

  1、所有从外部发往内部网络中目标端口为UDP4000-4009的报文全部丢弃。 

  2、所有从外部发往内部网络中目标端口为433的报文全部丢弃。 

  3、所有从外部发往内部网络中目标端口为UDP8000的报文全部丢弃。 

  4、所有从218.18.95.220(端口80)发往内网端口80的报文全部丢弃。 

  5、所有从218.18.95.220(端口443)发往内网端口443的报文全部丢弃。

2005年05月19日

DEBUG
命令行参数形式:
  格式:DEBUG [[驱动器号:][路径]文件名 [调试参数]]
  用途:debug将所指定文件装入内存,显示提示符“-”等待进一
步命令。若装入文件为.exe文件,按照重定位原则装入为可执行状态
。.com文件类似。若为其它类型文件则直接进行内存映射,由偏移量
100H原封不动读入内存。
  debug将在缓冲区为被调试程序建立适当的PSP(程序段前缀,
Program Segment Prefix)。在PSP中的偏移量80H为命令行的末尾。
而且在偏移量5CH和6CH由包含参数后面的可选参数构成缺省的FCB(
文件控制块,File Control Block)。
  进入时各寄存器初使情况:
  寄存器  .com程序             .exe程序
   AX     指定驱动器错误码     指定驱动器错误码
   BX     程序空间的高地址     程序空间的高地址
   CX     程序空间的低地址     程序空间的低地址
   DX           0                    0                                    SI           0                    0
   DI           0                    0
   BP           0                    0
   SP     0FFFFH或可利用的     不定
          内存空间上限减2
   IP     100H                 目标程序的的代码
                               入口偏移量
   CS           PSP            目标程序代码段址
   DS           PSP                  PSP
   CS           PSP                  PSP
   SS           PSP            目标程序堆栈段底
命令:
A:  编写汇编代码(Assemble)
  格式:A[地址]
  用途:程序允许在指定位置(若无缺省为IP指针位置)进行汇编  
        程序书写。
  细节:
      *所有数值皆为十六进制整数,数值后不带“H”
      *不支持文件管理用的目录表、宏标记、条件汇编
      *跳转指令后要直接书写十六进制地址不支持标号
      *数据类型若非默认类型,要以PTR加以指定
      *字符串操作要指定类型为B或W(如lodsb和lodsw等)及长度
      *用DB和DW接受数据定义,直按进行汇编
      *对内存地址加[]以与立即数区分

C: 内存内容比较(Compare)
 格式:C 地址范围  地址
       地址范围:做比较的第一个内存域始未地址或始地址和长度
       地址:    做比较的第二个内存域的始地址
 用途:*对内存中两个域的内容加以比较,以字节为单位。对发现有
       差别的内容及其地址用如下形式显示出:
           地址1  始位置  未位置  地址2
       *若地址范围或地址不含段地址,默认为DS的值。          
D: 显示内存内容(Dump)
 格式:D[地址范围]
       地址范围:给定显示区的始未范围或始地址和长度。
 用途:*内存内容显示指令,以十六进制和ASCII码形式显示指定范
       围内的内存内容。
       *若不指定范围,第一次按目标程序的CS:IP的位址开始显示。
       以后使用上次显示的未地址的下一地址为开始进行显示。
       *若不指定长度,则显示128byte的内容。计8行。

E: 数据的输入
 格式:E 地址 数值列表
       地址:    数据输入的内存始地址
       数值列表:从始地址输入的连续数据
 用途:*向内存区域输入数据。数据以十六进制形式,或以ASCII码形式
       均可。覆盖掉原有数据。
       *十六进制时要用空格、逗号或制表符加以分隔。字符串则要用单
       引号或双引号括起且区分大小写。
       *若不指写段址,则默认为DS中值。每写完一数据地址自动增加。
       *如省略数值列表,对应每一字节请求输入。点号前为该字节原
       始值,点号后请求输入。这时若按空格,跳过这一字节;按回车,
       结束输入;按减号或连字符,显示前一字节内容。    
     *出错时内存内容有可能已被改变。提示后终止。
       *字符串只能以数值列表的形式输入,不能按地址提式输入。

F: 内存填充(Fill)
 格式:F 地址范围 数值列表
    地址范围:数据输入的内存始本地址或首地址和长度
       数值列表:从始地址输入的连续数据
  用途:*将列表中数据写入内存。输入数据以十六进制或ASCII码形式。
     覆盖原有信息;若出错,显示出错信息,原有信息保留。
     *若未指写段址,默认为DS寄存器值。
     *列表中可有十六进制或字符串两种形式,各内容用空格、逗号、
     制表符隔开。字符串必须以单引号或双引号括起,区分大小写。
     *若要填充区域大于数据数目,列表可重复使用;相反,若列表
     比要填充区域大时,则自动截断后面的数据。

G: 程序执行(Go)
 格式:G[=地址][断点0][……断点]
       地址:          Debug开始执行的地址。
       断点0……断点9:指定的0—10个临时中断点。
 用途:*将CPU控制权由Debug转移给被调试中的程序。不设断点时,则程
       序的执行或是中途失败蚴钦=崾=崾保崾居小癙rogram
       termminated nomally”,即程序结束正常,控制权再返回到    
       Debug。
       *此时因数据有可能重写,若需再次执行,因重新装入。
       *地址中,如未指定段址,则使用目标程序的CS寄存器中的值。当
       地址省略时,则Debug使用目标程序的CS:IP寄存器的值开始执行。
       且为与断点区分,地址参数前必须加等号,否则将其认为是第零
       个断点。
       *断点参数可指定10个临时断点。当程序执行到指定的断点地址时
       则发生中止。与断点表内的次序无关,断点可按任意次序输入。
       *中止时,将会显示寄存器的内容、标志位状态及CS:IP指出的指
       令(也就是下一条将要执行的指令),然后是提示符“-”。
       *若没有装入可执行程序或程序内容未知,有可能进入死状态。
       *若目标程序的栈不起作用或太小,则可能引起系统“破碎”。

H: 执行十六进制算术运算(Hexadecimal)
 格式:H 值1  值2
       值1、2为0—FFFFH范围内的任意十六进制数。
 用途:*用来求两个十六进制数的和、差,对结果显示为值1+值2及值1-
       值2。如果值2 > 值1则显示其补码。
       *虽然很少用,但事实还是很有用的,熟练掌握。
                                                         
I: 端口的输入(Input)
 格式:I 端口地址
       端口地址:0—FFFF范围内的I/O端口地址。
 用途:用来读取指定I/O端口地址,并以2位十六进制数加以显示。
 警告:I指令将直接访问计算机硬件,不是所以错误检查都能进行,所以
       使用是必须小心。对某个外设控制器分配端口的输入操作,可能
       干涉系统固有的操作。对没有分配指定I/O端口的设备,或该端口
       为写入专用端口等情况,I命令都不能保证可显示。

L: 装入命令(Load)
 格式:L 地址
       或
       L 地址 驱动器 开始扇区 扇区数
       地址:    存放从盘中读出数据的内存地址。
       驱动器:  A=0, B=1, C=2, 以此类推。
       开始扇区:以十六进制数表示要最先装入的逻辑扇区号。
       扇区数:  以十六进制数表示要装入连续扇区个数。
 用途:*若输入了一个不完全的L命令时,则对下述磁盘文件进行装入:
          1在Debug命令行中指定过的文件;
          2由命令末尾参数N指定的文件。
       *在地址中若未指定段址,则使用CS中的值。若为可执行文件按重
       定位原则装入为可执行状态。    
       *装入后文件长度,或.exe文件程序的实际长度放入目标程序的BX
       和CX两个寄存器中。高十六位放在BX中。
       *若在命令行中给出所有参数,则不必用MS-DOS的文件系统访问磁
       盘。

M: 数据传送(Move)
 格式:M 地址范围 地址
       地址范围:被复制域的始末地址,或始地址和长度。
       地址:    数据复制目的域的起始地址。
 用途:*对内存中数据进行复制。目的域被覆盖。
       *若地址范围中无段址,则使用DS内容;若地址中无段址,使用地
       址范围中的值。


N: 文件名或命令末尾的参数(Name)
 格式:N 参数 [参数……]
       参数:插入到仿真的PSP中去一个以上的文件名或者是开关项。
 用途:*对磁盘读写操作L、W指定目标文件。


O: 端口的输出(Output)
 格式:O 端口  字节    
       端口:I/O端口地址。
       字节:写入I/O端口的0—FFFF范围的值。
 用途:向I/O端口地址写入一字节。
 警告:错误的操作将导致系统崩溃。

P: 循环或子程序处理(Procedure)
 格式:P[=地址] [命令数]
       地址:  执行的起始地址。
       指令数:执行的指令条数。
 用途:*循环或子程序处理。将循环、串指令、软件中断或子程序调用
       视为单语句。执行中了,显示目标程序寄存器内容、标志位状态
       和下一条要执行的指令。
       *若地址参数中无段址,则使用CS中的值。完全忽略地址时,则从
       程序中的CS:IP指定位置开始执行。

Q: 结束Debug操作(Quit)
 格式:Q
 用途:程序结束返回。对未保存的结果丢失。

R: 寄存器显示与更改(Register)
 格式:R [寄存器]
       寄存器:AX BX CX DX SP BP SI DI
               DS ES CS IP PC
               F
 用途:*若R不带参数,则显示所有寄存器的内容和状态标志、下一指令。
       *若指定新值,在显示内容后,给出冒句提示输入新值。回车结束。
       *对状态字F,在连字符“-”后以空格间隔输入新值,次序不计。
       *若直接回车,则跳过修改,寄存器内容不变。

S: 内存检索(Search)
 格式:S 地址范围  列表
       地址范围:想来你该明白是什么样了吧:)
       列表:    欲检索的一个以上的字节值或字符串。
 用途:*在指定的内存范围内检索列表的值。对每一个匹配的地址进行
       显示。
       *若起地址中无段址,默认为DS的值。
       *检索范围不得大于FFFFH
       *列表必须以分隔符(空格,逗号,制表符等)分隔;字符串要加
       单引号或双引号括起,区分大小写。

T: 程序执行跟踪(Trace)
 格式:T[=地址][指令数]
       地址:  执行的第一条指令的地址。
       指定数:执行的机器指令的条数。
 用途:*执行单条指令,显示寄存器及下一条指令。
       *在地址参数中若无段址,则默认为CS寄存器的值。
       *若全部省略,则由CS:IP寄存器指出的地址开始执行。
       *以后则顺序执行。
       *对ROM内的跟踪应使用T命令。
 警告:对Intel 8259 中断屏幕的内容(IBM PC及兼容机端口20H和21H)
       的更改,或者系统功能调用(INT 21H),不能使用T指令,对上述
       情况要使用P指令。

U: 反汇编(Unassemble)
 格式:U [地址范围]
 用途:*将机器指定解码为汇编语言的助记符。
       *地址范围中无段址时,默认使用CS值。
       *当始地址与实际边界不一致时,结果将不可信。
       *若不含末地址或长度,则自给定始地址起反汇编32个字节。
       *以后由前次U最后一指令的下一指令做32字节的反汇编。
       *若从没用过U,则于CS:IP开始进行反汇编。
       *只能对8086指令解码,对其它以DB来显示。

W: 写入文件或扇区(Write)                                                                            
 格式:W [地址]
     或
       W 地址 驱动器 开始扇区 扇区数
       地址:  待写入盘的数据在内存中的起始位置。
       驱动器:写入数据的盘的驱动器号(A=0,B=1,C=2,以下类推)。
       始扇区:写入数据的最前的逻辑扇区号(0—FFFFH)。
       扇区数:写入数据的连续扇区个数(0—FFFFH)。
 用途:*将内存中的文件或一个个扇区传送到磁盘上。
       *W若不带参数,或只有地址参数,则按BX:CX寄存器指出的字节,从内
       存向磁盘写入数据。此时的文件名是此命令前最后一个使用过的文件名
       ,或者是N命令中指定的文件,如果没有使用过N命令,则使用Debug命
      令行中指定的文件。
       *Debug的W命令,不能向扩展名为.EXE或.HEX的文件中写入数据。
       *这可用改扩展名的方法得到应用,让其能对.exe文件写入。
       *若无地址项,则认为是目标程序的CS:0100H。
       *该命令可不通过MS-DOS的文件系统直接访问磁盘的逻辑扇区。但必须
       以十六进制形式给在命令行中给定各参数。
       *W命令不能对用于网络上的驱动器进行逻辑扇区写入处理。
 警告:若参数有误,则可能破坏盘文件结构。
       请务必先搞清再作试践,特别是对硬盘的操作。            

我们是某著名国产防火墙的地区级总代理,牌子我就不说了,做了该防火墙将近一年多,期
间遇到了太多的问题,而且大多数都是产品质量问题。真是ft。

第一次出问题是改了个防火墙的地址内口,结果从内网就上不去了,与厂家联系答复“应该
”不会出现这种问题的,让把机器改成与防火墙内口地址的同一网段再试一试,ft,我们这
能折腾的都折腾了,而现在的问题是就是出这种问题了。与厂家多次交涉后答应派他们的技
术工程师过来,过了几天他们的人飞过来了,到还敬业,到了公司就开始折腾,不过折腾许
久未果后,说拆开看看,拆就拆吧。偶一直觉得防火墙内部挺神秘的,应该是类似路由器的
模块化设计吧,想着还可以开开眼界,恩。。。不错。谁知拆开一看,WK,果然是让我大开眼
界。PIII的CPU、ASUS的主板、D-LINK的网卡,Seagate的硬盘,KingMax的内存,要不是他们
的那个盒子,整个一兼容机。最搞笑的是因为没插显卡,每次启动的时候总会发出几声显卡
报错的滴滴的响声。
ps:现在的新的产品不会响了,看来是修正了这个“bug”,可以更好地糊弄人了。

第二次是去某大型的系统安装,客户本来用的是Checkpoint,结果在我们的极力鼓吹下(我
们主要理由就是Checkpoint的软件防火墙,而我们代理的该防火墙是硬件防火墙,客户也觉
得他们的应用如果用软的可能更不上,也想用硬的),对方决定改用该防火墙试试。其实想
想如果客户看到防火墙的里面,再看看防火墙用的OS,还会坚持用这?唉。。。。不说也罢

第三次是去某大学网络中心,对方当时还没决定下来用什么牌子的防火墙,原来是准备上Ci
sco的PIX,但在我们的合理分析+循循善诱下,决定试用一下该防火墙,第二天我们拉着一
台防火墙到了该校的网络中心。因为这次比较重要,所以厂家的技术支持工程师又过来了,
安装的时候就颇费了一番周折,那防火墙自带的那个管理界面真是烂,配上了内外口地址和
DMZ后,居然三口中有两口ping不通(此时并没有关闭icmp协议),厂家的工程师折腾了一会
儿,看在管理界面上也没法弄,就拿出他的笔记本接到了防火墙的内口上,telnet到防火墙
里面开始折腾,这次偶看到了他们防火墙的内核,呵呵。。。RedHat Linux 6.2。又折腾了
一阵,恩。。。这次三个口都好了,可以上机架了,这时校方的负责人因为突然有点事,就
说既然都弄好了那上机架的事就等他们自己弄吧。我们回到公司,想着这次应该没问题了吧
。几天后我们打电话过去问防火墙怎么样,他们说他们已经从机架上撤下来了,他们说有两
个口的接口有问题,要用手扶着网线才能用,手一松他们的校园网就瘫痪了。

我们只能说过来看看,到了网络中心,防火墙已经被扔到了桌子上,我们仔细观察后发现有
两个接网卡口的针已经陷进去了,所以造成接触不良,而那天厂家的技术工程师在弄的时候
,只是运气好,所以能勉强调试。而这完全是质量问题,也本应该在出厂的时候就检查好的

我们跟校方说口有点问题,我们回去带个口来换,回去后找了个新的接口,第二天又来到网
络中心,我们拆机箱的时候网络中心的人也在旁边看着,心想这次玩完了,要是让他们看到
里面不过是一台杂牌兼容机,那就没戏了。可这时又不可能把他们支开。果然,当拆开机箱
后,那些老师们都用很惊奇的眼光看着这台号称能支持120,000个连接、100M带宽的安全过滤
的防火墙的内部,不过只看了一会儿,老师们就摇摇头走了,这次看来是彻底玩完了。换完
之后,校方的说那就先放着吧,他们会再搬上机架的。几天后,校方的打电话来说他们还是
决定用Cisco的PIX
,这台防火墙就又被被我们抬回来了。

第四次是去某上市公司,他们用的是光缆接入,因为我们和信息部门的负责人关系较好,他
们也认为他们有安装防火墙的必要,所以,理顺陈章的,他们决定买我们代理的防火墙。不
过这时偶对这种防火墙其实已经没有多少信心了,虽然我们是它的代理商。

这次的安装调试又成了一次漫长之旅,先是调试完成后发现防火墙的有几个重要的功能居然
不能用!点了以后会报500错,真是ft。这时客户的网络已经停了一天了,与厂家联系后厂家
答复他们的技术工程师一会儿就telnet过来远程调试,好不容易等他们折腾完了,客户也答
应几天后签验收报告然后会寄到公司。这次心里挺高兴的,心想总算“比较顺畅”的安装调
试完一台防火墙了。谁知几天后客户打电话过来,说上次出错的那个地方又再次出同样的错
,而且客户需要的一个重要功能也用不了了,我让客户开了terminal services后,连过去自
己看看, WK,这防火墙还真是巨烂无比,我都没甚么好说的了。虽然后来又经过几次折腾已
经差不多好了,不过我的信心也差不多全没了。

其它的还有很多,比如我们自己用的这台网卡坏过两块,硬盘坏了一次。ps:硬盘坏这次最可
气,跟厂家联系后答复马上寄,结果等了半个月才寄过来。寄过来的硬盘软件上还有一堆问
题。虽然昨天厂家已经远程弄完了,不过这次调试的工程师顺便把密码也改了:(,还好我
开了Sniffer ,抓下了他的用户名和密码,还有他的操作步骤,可以继续研究他们的破烂(
没办法,我现在还在做这种防火墙的售前和
售后支持),不然以后他们又可以找借口说什么不是系统的问题了。

我真的很希望国货能强大起来,虽然大家都说老外的东西里面有后门,但如果你只跟我说国
产的东西安全,却让我三天五头的折腾,那我想如果在安全性和可用性之间选一的话,我只
能选可用性,并不是我不重视安全,而是我想没人能容忍自己的网络动不动就瘫痪,也没人
能容忍厂家的人总是找些客观理由来搪塞。而这些都是因为产品本身的质量问题造成的。

ps:公司的某大型客户已经决定上该防火墙了,这下又有的折腾了。现在只希望不要在该客户
面前拆开机箱折腾丢人了。

2005年05月18日

这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:

问题一:

使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?

我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?

问题二:

最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。

查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。

0、big endian和little endian

big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。

“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

1、字符编码、内码,顺带介绍汉字编码

字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。

GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。

从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。

这里还有一些细节:

GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。

在DBCS中,GB内码的存储格式始终是big endian,即高位在前。

GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。

2、Unicode、UCS和UTF

前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。

Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。

根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。

在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。

目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。

UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。

IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。

3、UCS-2、UCS-4、BMP

  UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:

  UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

  UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

  group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

  将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

4、UTF编码

  UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:

UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 – 007F 0xxxxxxx
0080 – 07FF 110xxxxx 10xxxxxx
0800 – FFFF 1110xxxx 10xxxxxx 10xxxxxx

  例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

  读者可以用记事本测试一下我们的编码是否正确。

  UTF-16以16位为单元对UCS进行编码。对于小于0×10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0×10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0×10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。

5、UTF的字节序和BOM

  UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

  Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

  在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

  这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

  UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

  Windows就是使用BOM来标记文本文件的编码方式的。

6、进一步的参考资料

  本文主要参考的资料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

  我还找了两篇看上去不错的资料,不过因为我开始的疑问都找到了答案,所以就没有看:

"Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
"Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)

  我写过UTF-8、UCS-2、GBK相互转换的软件包,包括使用Windows API和不使用Windows API的版本。以后有时间的话,我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。

  我是想清楚所有问题后才开始写这篇文章的,原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间,竟然从下午1:30写到9:00。希望有读者能从中受益。

很多朋友在网上冲浪时,经常会遇到有些网页可以顺利地打开,而有些网页却无论如何也打不开,而在其它电脑中却又可以轻松地打开。出现这种情况,最大的可能就是你的IE浏览器中招了,而Hosts表文件往往是祸之源头。

一、什么是Hosts表文件

Hosts表文件是一个没有扩展名的文件,但是它属于文本文件格式的文件。你可以使用记事本程序对其进行编辑。Hosts表文件中存放的是一些常用的网站主机的域名和其对应的IP地址。当我们在使用浏览器浏览一个网站时,在地址栏中输入网站的域名并回车后,系统必须通过某种渠道将这个域名转换为其对应的唯一的IP地址,这项工作通常是由DNS(域名解析服务器)服务器来完成的。而在系统将域名将给DNS服务器处理之前总是先在检查本地的Hosts表文件,看其中是否已经有相应的域名与IP地址的对应关系,如果有就会直接采用,因而会节约大量时间。

正因为这个原因,假如Hosts表文件中的某个域名与IP地址产生了错误的对应,当你在浏览器中输入这个域名试图打开其对应的网页时,就会出现打不开的情况,而那些没有映射错,或是没有在Hosts表中有相应记录的网站则可以正常地打开。这就是上面我们提到的为什么有些网址不能打开,而在其他电脑中可以顺利地打开的原因之所在。很多恶意程序经常会闹这样的恶作剧。

二、中招后的解决方案

知道了原理后,假如我们的浏览器中招而导致某些网站不能正常打开的话,我们就可以通过修改Hosts表文件来解决了。Hosts表文件在系统中的位置,Windows 9X系统存放在C:\Windows目录,Windows NT/2000系统,其保存在c:\winnt\system32\drivers\etc目录,Windows XP系统保存在c:\windows\system32\drivers\etc,如果找不到的话,可以通过系统的搜索工具进行搜索。找到后,直接用记事本将其打开,然后将除了“#”开头的其它行内容全部删除,例如“127.0.0.1 onlinestore.smgbb.cn”,最后单击“文件→保存”将其保存即可。当然,你也可以选择性地删除那些被屏蔽了的而你又想访问的网站,这样其他被屏蔽的网站则不会受影响。

如果你嫌上述手工方法太笨拙,你也可以通过专门的工具来达到目的。上网助手2005(下载地址:http://dl.3721.net/download/assist4.exe)就可以让你轻松地修复Hosts表文件了:

下载并安装了上网助手后,在IE地址栏中找到“上网助手”图标,单击右侧的黑三角形,选择“修复IE→IE修复专家”,在打开的窗口中选择“编辑Hosts表”选项卡,如图1:


 

图1

图1

如果你不想一条一条地更改,直接单击“清空HOST表”按钮,最后单击“立即保存”按钮即可。否则你可以在列表中勾选那些被屏蔽掉而不能访问的网站域名,再单击“删除→立即保存”按钮。

三、经验之谈

当你遇到某些网站打不开,而有些网站可以顺利地打开,除了在IE浏览器中设置了网址过滤之外,Hosts表文件被动了手脚就是最可疑之处了。通过上面的方法,一般都可以轻松地解决。鉴于此,一些烦人的网站(例如,百度插件安装页),我们倒可以利用这个特性将其“屏蔽”掉,方法很简单,只要在Hosts表文件中的尾行中追加类似于:127.0.0.1 bar.baidu.com(127.0.0.1与bar.baidu.com之间用空格分隔开)一行,最后保存并退出Hosts表文件即可。你也可以使用上网助手的Hosts表文件编辑功能来操作,在图1所示的窗口中单击“添加”按钮,然后在下面的“IP地址”和“域名”栏中分别输入127.0.0.1 和bar.baidu.com,最后单击“立即保存”即可。按同样的方法,可以将其他不想让其在本台电脑中可以访问的网站“屏蔽”掉。

2005年05月16日

    [引子]
    抵制日货这一周成了网络流行词,相关行动也民间热闹一番,其实,可以抵制日货的行动便很多,不必仅仅拿数码产品说事,那仅仅是低端产品而己,而且是一批拿父母亲钱去消费为主的一代人行为:他们真会长期抵制日货才怪(?)。本文便是另一个抵制日货行动,有兴趣的网络人士应该吁一下,让大家用.cn爱国、不用.com抵制日货吧!

    [网站访问流量费去向]
    申请域名空间、托管服务器时,有一个协议条款是“网站访问流量”限制,这个看似简单的协议条款其实与ISP的经营成本中出国境流量费有关。据业内人士透露,在中国互联网发展初期,中美签订互联网合作协议时,因为中国用户少,出境访问多(当时国内ICP几乎是稀有之物),因此访问出现单向流量,美方要求中方付钱而中方无任何可以讨价还价本钱。后来国内出境访问比国外进境访问少了,美方也从未修改此不公平条款。在这些网站访问流量费中,以第一次点击域名占的比例为最大,据说此项支出目前达到每年数百万美金以上,而且仅仅是由于访问国外管理的.com,.net,.org,.biz,等非.cn域名带来的。   

    [全球13台根服务器]
    据互联网技术专家介绍,访问国外管理的.com,.net,.org,.biz,等非.cn域名流量,是指为了寻找域名相应内容存放处、而先向分布在全球的全球13台域名“根服务器”带来的。而这13台域名“根服务器”有一台放在日本,即当您输入.com,.net,.org,.biz,等非.cn域名时,1/13的可能先到日本访问,为日本带去访问流量,这就是注册.com,.net,.org,.biz,等非.cn域名时,用户访问的支持日本互联网发展行为。

    [抵制日货行动本质]
    这个问题笔者认为,是不给日本企业带去商业机会,即他们的产品或服务在中国无市场,这就是抵制日货行动本质,目的是不让这个缺乏反省自己历史的民族经济受到创伤而改变。这是一个民族文化影响国家间商业贸易走向的抗争行动,当然其效果不是一两天会见效、更不是简单一句话可说清楚。

    [注册.com域名是助日本]
    以上说明,大家可以明白,注册.com,.net,.org,.biz,等非.cn域名时,用户上网访问这些网址的第一步便是给日本带去访问流量、支持日本互联网发展行为。因此,当互联网满地呼吁“抵制日货行动”时,这些上网呼吁者是否也呼吁一下:别注册.com,.net,.org,.biz,等非.cn域名,这样才叫抵制日货行动,对吧!

    sz1961sy 2005.4.11. 北京 16:19