随笔 - 59, 评论 - 580, 引用 - 50

导航

关于


微软提供的免费计数器

山不在高,有仙则名。水不在深,有龙则灵。斯是陋室,唯吾德馨。苔痕上阶绿,草色入帘青。谈笑有鸿儒,往来无白丁。可以调素琴,阅金经。无丝竹之乱耳,无案牍之劳形。南阳诸葛庐,西蜀子云亭。
子曰∶“何陋之有?”


My name is BEN.
This is my master's "doghouse". hehe...

标签

每月存档

最新留言

广告

【第1页/共2页,18条】
首页
前页
1

读后感——白话面向智能体编程(Agent Oriented Programmig, AOP)

一直以来对于什么是AOP没有太深入的概念,直到读完白话面向智能体编程(Agent Oriented Programmig, AOP)[1]之后仍然是没有很深入的认识。也许日后有机会可以深入了解一下,不过今天想将读完该Blog之后的想法记载于此,尽管这样的思考也许挺幼稚的。我对于这些概念没有太多的知识,如果认识有误欢迎指正(通过交流获得知识我觉得是比较有效率的)。

  首先说明一下,这里的AOP当中的A是Agent,而不是Aspect。虽然目前我没有摸清楚Agent和Aspect的具体差别在哪里,但是可以肯定是有区别的。我想Aspect-OP应该是强调概念与实现的一对一映射,其中单一概念与单一职责原则比较接近,单一实现我暂时找不到比较接近的概念。关于单一实现可以这么说:我们大家都知道MVC的模式、或者一些其它的模式,这些模式其实通过我们口中说出来只是一种想法,或者说是概念。而最终形成代码的才是实现,可是也许会有很多地方会用到MVC,于是对于MVC就会有各种各样的实现。(参见“白话面向智能体编程(Agent Oriented Programmig, AOP)”系列第一篇一开始引用的文章The Ted Neward Challenge (AOP without the buzzwords)[2],原文的链接无效,这个是google出来的。)引用[2]的作者在文中提到他的研究当中最夸张的情形是,在某个软件当中有一种设计上的概念竟然有10万个(次)实施。(In one system I've studied, the concept:implementation ratio for that single requirement is well in excess of 1:100,000. )也许这么说还比较难理解,那么我们说说记录异常(to log failures),可能我们会在软件当中随手写道:
MessageBox.Show(ex);
又或者
logfile.WriteLine(ex.Message);
还可能是
myLogger.LogObjectTypeA(ex, objectA);
myLogger.LogObjectTypeB(ex, objectB);
...

  而事实上将错误记录下来应该是一个问题,或者一种设计上的概念,然而却会在软件当中存在多种不同的实施方案。这种情况对于维护来说可能是一件相当麻烦的事情,因为本来都是同一个概念里面的东西,如果我们因为概念上的问题需要进行更新维护,可能就需要对所有不同的实现进行维护,这将会是一件相当烦人的事情。

  上面说的是我对Aspect-OP的理解,那么Agent-OP呢?我想“白话面向智能体编程(Agent Oriented Programmig, AOP)”的系列说的还是比较容易理解的,其大意是,我们需要一个跟真实世界更加接近的模型。在Agent-OP里面有很多与OOP不一样的思考方向,例如“有心智”或者说“有目标感”,我想这一点是比较重要的概念。说到OOP我们自然能够想到“对象”,对象的其中一个作用是划定知识界限——什么属于这个对象以内的(比如对象当中的成员),什么属于这个对象以外的。这一概念对于软件界是一个里程碑,应当说是非常有意义的。然而我们也应该能够体会到OOP本身并没有对“驱动力”进行探讨,而事实上目前的软件中的“目标感”更多地是通过下列两种力量驱动的:用户,以及软件背后的设计。

  用户驱动并没有什么问题,毕竟使用软件的是人。然而通过软件背后的设计来驱动“目标感”,我一直都觉得不是很顺畅——因为这种设计相对来说是静态的,基本上不会根据环境的变化进行相对的调整。比如引用[1]当中提到的一个“鸡块熟了之后捞起来”的例子,也许我们会设计一个ChickenClass和一个ChefClass,ChickenClass有一个事件Cooked告诉ChefObject某个CheckenObject熟了,然后我们就会有下面的代码(C# 2k5):

CheckenObject.Cooked += ChefObject.Checken_Cooked;

  这个设计的后果是,不管厨师有多忙,鸡块觉得自己熟了之后就会踢厨师一脚,这时候厨师不管情愿不情愿都得把鸡块捞起来。事实上目前的绝大多数软件中的“厨师”本身根本就没有情愿不情愿想法,只不过是一个奴隶、一个工具而已。有人会说,有的软件中的“厨师”是有心智的,但我想还是与Agent-OP是有区别的,其区别可能在于两个方面:

1、有可能这只是无意识造成的偶然结果;
2、如果是有意识设计出这样的“厨师”,很有可能并非用的Agent-OP的工具。(可能制作的方法并不规范,可能存在一些问题。)

  也许Agent-OP比较前沿,我自己也说不清楚,换一个面向过程和面向对象来说吧。首先让我们时光倒流20年,假设我们正在使用C语言。我们能够将某些知识限定到某个范围以内吗?我想可以用struct,我们可以设计一个v-table,就像C++背后做的那样。于是我们也一样可以写出类似obj->Member(obj2); 这样的东西来,例如:(obj.v_table[ID_Member])(obj2);

  可这仍然不是OOP,还有很多的问题是需要有专门的OOP工具才能够解决的。Agent-OP也一样,我们目前如果要制作一个Agent-OP的软件,工具还是相当缺乏的,甚至连人的思想也相当缺乏的。不要忘了,光有OOP的工具,如果使用的人还是以面向过程的方式去思考和设计,最终出来的东西也不是OO的。我想Agent-OP也一样,例如让我来使用Agent-OP的工具兴许就弄不出什么花样来。

  我为什么会觉得需要Agent-OP呢?因为Agent-OP应该能够提供一定的自适应能力(比如什么时候鸡块算是熟了,什么时候我有时间去处理,以什么样的方式去处理等),有了自适应性才有可能提供自组织能力。没有自组织能力的系统,其整个设计实际上仍然是硬梆梆的。关于这点我们可以用制造行业的发展来做对比:现在的制造业有一种较新的概念叫做“柔性制造”,与此相对的是“刚性制造”。对于“刚性制造”来说,生产线的各个机构的运动方向只能够或者前后或者左右,顶多可以换一个模子或者刀具,因此其任务和目标是定死的。当任务或者目标发生改变的时候,比如原来是造汽车门的,现在要制作飞机机舱门了,那么整个生产线就报废了,对于软件来讲就是需要重新设计。但“柔性制造”就不一样了,生产线上的工作机构有许多的自由度,要制作什么完全依靠工控程序的控制,因此面对任务和目标的变化,只需要更换工控程序就可以了。对于软件来说,我们也希望能够仅仅替换某一个很小的“智能部件”,就能够在一定范围内改变任务和目标,因为我们都知道软件的需求(也就是任务和目标)的改变往往是代价非常高的。要达到这一目的,“智能部件”必须能够自行适应其外部的系统状态,或者说能够与系统的其它部分自行组织起来。要做到所有这些,以目前的技术条件看起来是相当困难的。

  说到这里,也许已经看到我对于Agent-OP的理解跟引文[1]中所述的有一定的出入了。正是因为这些出入,我对于原文的某些观点有一些不同意之处,且容我细细说来:

痒处一:OO并没有对现实世界中的实体加以区分
  引文[1]的作者认为需要区分“发票”和“员工”,因为“发票”是没有智能的死物,而“员工”是有智能的活物。死物只是被动的接受各种的操作,而活物除了会主动的进行操作之外,还有可能主动的进行调整,甚至是拒绝操作。
  然而我认为现实世界如此,并不代表虚拟的世界也必须如此。难道虚拟世界就不能够如同动画片或者科幻片中的想象那样,存在具有思想感情的“发票”吗?更尖锐一点说“机器(人)”是死物呢,还是活物?反过来也一样,“员工”一定是活物吗?还是那个例子,如果你家里有一个机器人员工你打算怎么办?当然,这样的例子比较变态,但是我想从中说明,虚拟世界的对象是否应该具有心智,并不取决于现实世界中影射的对象是否具有心智。而对于作者说的“可以引入计时器或者多线程,但是总是因为与现实不符而不爽”是非常认同的,然而实际上引起这一问题的实质并非在于虚拟对象与现实对象在心智上的映射不能相对应。关于这一问题,我想在后面的条目中会有所揭示。

痒处二:同步和异步被人为地剥离。
  因为[1]的作者认为,操作者不应该关心到底是使用同步方式还是异步方式,这个问题应该由被操作对象自行决定。
  然而我觉得这种想法可能存在问题。
  问题一:被操作对象必须具有心智才能够决定到到底是同步还是异步,假如被操作对象是一张发票,那么这如何进行解释?
  问题二:事实上现实世界绝大多数情况下都是以异步的方式进行的。老师说“同学们翻开第78页”,然后无论同学们翻不翻书,老师都会继续说下去。上司向下属布置任务,也只有上司在不停的说,决不会每一句话都等下属确认“明白”之后才说下一句话。此外,现实世界如果需要进行同步,通常都是双方都有决定权的。老师说“同学们翻开第78页”,如果哪个同学还没有翻到那一页,深怕漏听了哪一句话,肯定得说“老师等一下,我还没有翻到那一页”。(高考复习给出重点复习内容的时候大家没少遇到这种情况吧,大学期末考试老师给出考点的时候也没有少遇到这种情况吧?)而上司如果深怕下属没有想明白某句话的时候,也会问下属“明白了没有?”或者“有没有什么问题?”,等到下属说“明白”或者“没问题”之后才继续说下去。
  问题三:其实现实世界当中的同步是通过等待他人“虚拟”出来的概念,正如计算机世界的异步是通过独立线程“虚拟”出来的概念。只不过目前对于计算机世界来说,被调用方向要主动要求调用方等待(或者不要等待)是一件较为困难的事情。除了软件方法当中缺乏这样的概念和工具之外,这也对调用方提出了更高的知识要求:原来只要知道“同步”(或者“异步”)调用对方的处理方法就能够完成工作,而现在却还需要知道如果对方要求“异步”(或者“同步”)的话怎么办。较为简单的办法是调用方继续假装一切按照同步的方式进行,但是这样的话有何意义呢?反过来也有类似的问题。当然,问题总是能够解决的,只是这种解决所付出的代价和获得的回报之间是否存在利益。很明显,以目前的技术条件不可能在所有的操作面前我们都能够从中获利。(假如是工作流引擎的话,可能性会比较大,毕竟工作流比较贴近现实,异步的操作实际上比较多。)

痒处三:无法自然地模拟现实世界中的感知能力(Sensebility)
  引文[1]作者认为,目前软件的问题在于缺乏感知能力。例如:“如果鸡块的颜色由肉色转变至金黄色,俺就必须做出相应的操作/处理:把鸡块捞出锅来。”而目前的软件设计更多的是有鸡块引发“熟了”这个事件,然后因为“我”订阅了鸡块的“熟了”事件因而此时被鸡块“踢了一脚”,“我”就立刻按照程序把鸡块捞出来。从这种描述看来,“我”并不是通过观察“鸡块”的颜色是否变黄来判断“鸡块”是否“熟了”。
  而我认为这种想法也很有问题(也许只是作者的例子举的不恰当)。

  首先,这里并不是没有进行观察,只是观察的是一个现实世界当中不存在的观察量。假如我换一种方法,变成订阅“鸡块”的颜色值变化事件(BackColorChanged),当颜色值发生改变的时候鸡块就引发事件。而如果“我”发现“鸡块”的颜色偏黄到一定的程度((BackColor.R + BackColor.G)/BackColor.B > threashold),“我”就捞起“鸡块”。怎么样,现在改成观察鸡块是否变黄来决定鸡块是否该捞起来了吧?可是你一定还是觉得不对,因为根本原因不在观察什么,而在于“我”被鸡块“踢了一脚”。
  在现实世界如果你被鸡块踢了一脚告诉你该捞起来了,你也许会觉得不爽,但在计算机的世界未必如此。假如你给KFC开发一个自动捞鸡块的机器,客户一定期望着鸡块熟了的时候能够踢机器一脚,让它立刻把鸡块捞起来。而且在可以有直接的、积极的、主动的方法进行沟通的情况下,为什么非得要屏蔽这一方法,舍近求远舍本求末的采取间接的、消极的、被动的方法进行沟通呢?现实世界的鸡块之所以不会再熟了的时候踢你一脚,是因为现实世界的鸡块确实是死物,并不是你不期待它会踢你一脚。如果鸡块炸糊了,你会感到更不爽的。再举一个例子,为什么现实世界的烧水的水壶还带一个“哨子”,水烧开了就叫呢?就是因为实际上人们期望水烧开的时候水会“踢”你一脚,让你赶紧把火给关了。虽然水是死的,我们却希望让它活过来,不是吗?
  因此我觉得这里是本末倒置了:很多时候我们之所以希望贴近现实,只是因为我们期望它能够跟现实当中那样方便;而如果现实当中的情况不符合我们的期望的时候,我们就不应该按照现实中的那样去做。

  其次,这个例子之所以能够引起我们的感触,是因为我们需要对“鸡块”的颜色做出判断,但是计算机竟然不需要。而且现实当中每个人对于“鸡块”的颜色变成什么样了才算熟,并没有一致的答案。其根本原因在于现实世界有很多很多的“量”,大体可以分为两种“可观测量”和“不可观测量”。鸡块的便面颜色属于可观测量,是否熟了属于不可观测量。于是我们会面对根据可观测量猜测不可观测量的问题,而每个人之所以会有不同的答案,原因在于猜测过程当中需要用到很多知识,也包括经验。每个人的知识不同,因此猜测的准确度就不可能相同。在这个例子当中,我们的根本任务是根据不可观测量的变化作为进一步操作的依据,也就是说“如果鸡块熟了,就捞起来”。但是“熟了”这个量不可直接测得,因此只好根据可观测量猜测不可观测量的值。可是如果现在给你一个神奇设备,能够直接告诉你鸡块“熟了”,你还会多此一举去判断鸡块的颜色吗?也许会看一下,以防设备坏了不知道,但是如果设备没坏,我想你是不会费神去根据鸡块颜色来判断鸡块是否熟了。
  简而言之,如果软件中的鸡块能够提供“熟了”的信息,就不应该屏蔽它然后提供“表面颜色”来让厨师猜测,此举舍近求远,浪费脑细胞——除非你在设计一款猜谜游戏,玩家扮演的是“厨师”这个角色……
  当然,从另一个角度看,我们也确实可以看到,现在常见的商业软件方法并没有“不可观测量”这个概念(但是在科学计算里面经常可以看到,不过也不是作为软件设计概念存在的),更不要说对此有什么解决方案了。如果我们正在设计的部分属于跟现实世界进行互动的部分,那么这一概念是不能够忽略的。对于工作流引擎来说就是这样的一种情况——什么时候属于“完成”了或者“出状况”了,有的时候并没有一个直接可观测得标志能够表明这一情况。如果软件足够智能,就应该考虑根据可观测量对不可观测量进行猜测的能力。

  最后,作者在文中接近最后所提出的一个说法,我想要提出比较强烈的异议。作者说:
  “在现有的delegate解决方案中,我们只能针对实例(Instance)进行注册,而不可以针对类型(Type)进行注册。……如果能够提供针对类型的注册机制,只要将俺的后续操作到鸡块类上注册一次,在感知范围内的所有鸡块,管他是十块还是二十块,都能被俺感知到颜色上的变化并执行正确的后续操作,这样会来的更简洁,更自然。
  首先,至少在.NET里面类型上面完全可以有delegate/event,比如说AppDomain.UnhandledExceptions就是类型上的事件,针对类型进行注册在.NET里面是完全可能的,并且不难看到。因此说这个并不是OO的问题,顶多属于某种语言内部的问题。其次,这种通过注册到某个类上面来对所有正在炸的鸡块进行观测,是一种很不明智的做法。因为这不属于类型上面的知识范畴,而应该属于某个锅以内的鸡块集合的范畴。假如现在有三个锅正在炸鸡块,那引文[1]作者的想法可就得挨屁股了。

  不过话又说回来了,我非常认同作者说的其中一点,那就是:不应该由鸡块决定什么时候被捞起来,而应该由厨师来决定,尤其是要根据他自己所处环境的其他状况来决定——海啸来了还管鸡块干什么,赶紧逃命吧!这是目前的模型所欠缺的,不管厨师的情况如何,鸡块熟了都会引起厨师的相应动作。当然了,你可以这么写:

PriorityQueue needToBeFishedOut = new PriorityQueue();

private void Chef_ChickenCooked(object sender, EventArg e)
{
    needToBeFishedOut.Enqueue(sender);
    needToBeFishedOut.BringUpPriority();
}

然后再弄一个线程或者计时器进行相应的处理。然而正如作者所言,很不爽。好比让你用C来写真正OO的程序,用asm来写网页,或者用小刀来刻硬盘。工具不对,做起来既费劲又不规范,因此Agent-OP确实需要发展。

最后,我还是要补充一句,OOP和Agent-OP属于不同层次的概念,因此Agent-OP和OOP的关系更像是Class和Method的关系,前者不可能替代后者,并且应该在后者的基础上发展。(我甚至觉得Agent-OP已经不属于语言范畴的东西了,不一定会出现像OO出现之后,世界上所有语言都向OO的方向发展那样的壮观场景了。)

posted on 2005-07-12 14:59:00 by sumtec  评论(7) 阅读(4739)

如果从流量的角度讲,还是任重而道远……

不过从质量的角度讲,那就是另外一回事了。

   blogchina.com/     Go to http://www.blogchina.com/
www.blogchina.com

  

Average Traffic Rank: 516
Average Customer Review: 5 out of 5 stars Based on 3 reviews. Write a review.



  blogcn.com/     Go to http://www.blogcn.com/
www.blogcn.com

  

Average Traffic Rank: 843
Average Customer Review: 2.5 out of 5 stars Based on 2 reviews. Write a review.




   blogdriver.com/     Go to http://www.blogdriver.com/
www.blogdriver.com

  

Average Traffic Rank: 2,370



      Go to http://www.yourblog.org
www.yourblog.org

  

Average Traffic Rank: 2,436



  cnblogs.com/     Go to http://www.cnblogs.com/
www.cnblogs.com

  

Average Traffic Rank: 18,188



   blog.joycode.com/     Go to http://blog.joycode.com/
blog.joycode.com

  

Average Traffic Rank: 20,362



   seov.net/     Go to http://www.seov.net/
www.seov.net

  

Average Traffic Rank: 64,846

posted on 2004-11-11 18:19:00 by sumtec  评论(54) 阅读(4527)

从一个气压计想到的

从一个气压计想到的事先声明,本文章与技术没有实际关系。不喜欢的跟我讲,我立马从首页撤下来!
不知道大家读过一个笑话没有:
有一个物理学的教授邀请了他的一位朋友——另外一名非常著名的物理学家,来帮忙评判他的一个学生的考卷,其中有一道题是这样的:你现在有一个气压计,如何用这个气压计来获得一栋楼的高度?他的学生是这么回答的:先度量气压计的高度以此作为单位高度,然后度量该楼一级楼梯台阶的高度,输出每一层楼有多少个台阶,一共有多少层楼,然后四者相乘即可得出高度……
这位教授实在觉得不知道怎么评判比较好,一方面觉得比较有创意,另外一方面跟气压方面的物理知识一点关系都没有。他的朋友建议让那个学生再来做一次这道题目,当然,是用完全不同的方法。如果他能够用比较技巧性的,通过复杂数学计算的物理学方法做出来就算他通过。
当那一个学生来到这两位面前,并了解了他们的意图之后,开始苦思冥想。当教授和他的朋友都以为他做不出来的时候,他说了一个令他们目瞪口呆的答案:
嗯,首先,用一根一米长的绳子绑住这个气压计,然后到楼顶上作单摆运动,计下周期T1,然后到楼底下做同样的实验,记录周期T2。根据单摆的公式,我们已知周期T,单摆摆长L,就可以求出重力加速度g。再通过万有引力定律,已知g,地球质量M,就可以求出离地心的半径R。T1算出R1,T2算出R2,R1-R2就是楼的高度。
看到两个人愣在那边,这个学生得意地说:我刚才想了那么久并不是想不出来,而是想出来太多的东西了,要仔细考虑一下那一个更符合你们的要求。当然,我知道你们想让我通过气压方面的知识来得到这个题目的答案,不过那样太没有意思了,谁都知道答案是什么样的。
教授就问了,那你还有什么样的答案呢?学生说:比如我可以用一根绳子绑着气压计然后从楼顶吊到楼底下,或者用气压计来做一个自由落体运动,再或者测出气压计的高度和它太阳下的影子高度,再测出大楼的投影长度。实在不行了,我可以把这个气压计送给楼底下看门的老头子,让他告诉我大楼的高度。

这是一个笑话,所以从这里想出来的大约都是胡诌,就随意胡诌一下吧:
1、根据气压方面的知识来计算大楼的高度,也许就是最为传统的软件工程方法,CMM等之类的东西。

2、如果真的以气压计作为单位测量台阶高度来计算大楼高度,也许跟手工作坊大生产比较象。

3、要是你一个人来做实验,比如用绳子吊着气压计到大楼底,那么也许会因为不小心碰到二楼阳台的晾衣杆,以为到大楼的了,结果数据出错。所以这个要两个人来做,一个在楼顶吊着,一个在楼底下看着。这么做的好处很多:除了可以防止上面那种人为失误之外,如果在楼顶上吊气压计的兄弟胳膊实在是酸了,可以让楼底下的哥儿们上来替换一下。当然,楼下的兄弟通过观察绳子的情况,也可以知道楼顶上的兄弟是否睡着了。看出来了吧,这就是结对编程的好处。

4、自由落体运动的方案看起来不错,如果一切都是比较接近理想状态的话。可是如果正好有一个往上吹或者往下吹的风呢?所以测试之前最好在大楼中间的地方来一个监测,看看到达正中点的时间是否正好是总时间的二分之根号二,如果不是的话可以断言测试失败,至少这个方案有问题。这个时候我们得想办法把风去掉(比如打电话给上帝),不过在我们真正遇到这个问题之前我们可以假设事情就是理想的。不过这么做最好有一个伙伴跟你一块来做,当然了,TDD最好是结对的。

5、用气压计收买看门老头确实是好办法,完全不需要动脑筋,我喜欢。其实这个我们更应该动这样的脑筋,其实每一个国家安全局以及间谍机构里面的人都是这么干的,而且通常很漂亮。什么?计算机界里面有没有?有,黑客啊!没有听说过后门吗?一般的后门都是小打小闹的,据传闻某国政府在某个操作系统里面可能安有后门,如果这是真的,那肯定是收买老头子方案的超大型翻版。所以不要相信任何关于绝对安全的鬼话,那根本是不现实的,除非全人类都没有任何欲望。

6、世界上还真有人用单摆的方法来得到大楼高度的吗?天啊!那多么烦人啊!如果让我来做这个实验我肯定会疯掉的!想一想为了让大楼顶端和大楼底端得到的T值的精确度足够,我们得测量多少个周期的单摆运动啊?估计我睡着了都不会得到满意的结果的。(呵呵!哈哈!)笑?谁在笑?还真别笑!我们以前就是这么干的,不要说直接写机器代码的那个黑暗时代了,就是C语言的时代我们也不见得好多少。那个时候所有人都在不停的重复的颠来倒去的翻来覆去的做一些实际上完全一样的工作,而且所有人做的东西几乎都是重复的,现在想想我宁愿去睡觉。我们就是这么走过来的,没有这些工作我们也没有如今的舒服。话又说回来了,人类确实是通过这个方法来得到有关重力加速度的,虽然这是几百年前的事情了。

7、用三角函数求大楼高度(就是那个测投影的方案),是一种以小见大的方式。当然了,这种方式需要评判答案的人有一定的想象力——如果气压计的高度和它影子的长度成一个比例的话,这栋大楼也应该一样。在你让对方接受这种方式计算出来的答案以前,我们必须先让对方想象一下上面所说的场景,并且接受这么一个其实无法直接证实的事情(就大楼和气压表两者而言)。我们做软件的时候也经常需要这样,首先弄一个原型出来让客户看看,如果客户接受的话就需要一个舌头能够打活结的人来说服客户:如果我们的文档一步一步按计划出来,那么最终产品就是你们想要的东西,跟你们看到的那个原型意思是一个样的。

8、如果你对于上面的一些方案感到可笑,是因为你觉得从实际角度看,每个地方都存在误差,甚至你觉得你无法通过这些实验来得到准确的大楼高度,那么也许你是一个程序员;
如果你对于上面的一些方案感到可笑,是因为你觉得过程方面完全被忽略了,比如缺乏每一步实验步骤的描述,那么也许你是一个设计师;
如果你对于上面的一些方案感到可笑,是因为你觉得这些方案本身的大方向就错了,比如所用到的物理定律有问题,那么也许你是一个架构师;
如果你对于上面的一些方案感到可笑,是因为你觉得这些方案根本没有考虑到一些最基本的问题,比如说他不赚钱,那么也许你是股东,搞不好就是董事长;
如果你对于上面的一些方案感到可笑,那么对不起,得分两种情况:
a、我就觉得该这样做,那个谁,过来给我把它做出来,那么也许你是CEO。
b、不知道你在说什么,那个谁,把这篇帖子给我删了,那么也许你是LHS(幽默感缺乏综合症)。

9、其实我最关心的是,有没有更加恶搞的解题方法? 不过必须和气压计有关,并且从方法上是不同的。比如说用气压计收买楼顶上的清洁工,那就没有意义了。
10、这篇文章昨天就写好了,没有Post出来,是因为受到情绪的影响。今天Post出来没有关系吧?

posted on 2004-10-31 23:35:00 by sumtec  评论(22) 阅读(4624)

给各方的一个预警信息

 今天我才知道我在博客堂的Blog被人污染了,有人在回复里面贴这种东西:

为了避免有人认为我是在这里对其宣传(这个罪名可是担当不起),因此这里截断了,只是为了显示证据。这样的回复一共有四个,每一个的用户名是一样的,但是里面的连接却都不一样,我已经全部删除了。不知道这个现象以前有没有发上过,反正我是没有遭遇过,一直以为只有那些很垃圾的论坛才会被这种东西骚扰,看来这种骚扰哪里都会存在。其他的诸位博客看来得小心你自己的blog里面也留有这样的回复而不自知,所以经常管理自己的blog还是必需的,至少从这个角度讲是必需的。

另外开心和dudu是否都要看看这个问题是否需要注意了,至少我觉得会有很多人不愿意看到自己的blog里面有这样的留言。如果说现在是小规模个别事件还好说,如果出现大规模同类事件是否会引起大量的投诉,甚至某些部门也出面了,那就比较麻烦了,还是提前准备比较好。其实出现这种现象也许也算是一件好事,说明网站出名了。但是马上我又想到另外一件事情了,你说会不会有DOS攻击之类的事情呢?这个就扯得比较远了。

其实我也担心是否有人给我结仇了,故意这么损我的……如果是这样我首先要反省,说话还是需要更加客气。不过贴这种东西的人是不是需要小心一点,惹毛了一堆developer(多数是精英)也不是什么好玩的事情。(想想对方还不一定认识字呢……)

posted on 2004-10-26 11:44:00 by sumtec  评论(11) 阅读(1630)

这年头,还有人用C++的吗?

最近在时间的细屑里面挤出病毒般大小的时间来看GF调不出来的程序,简直是郁闷死人了。又要看好多年没有真正用过的C++,真是一种头痛欲裂的感觉,在一次感受到C++的疯狂之处……(这个程序其实之前确实是在用C++写的,后来因为某种原因,放弃了C++当中的++部分,用了几乎纯粹C的功能来编写。准确一点讲,标题应该是“这年头,还有人用C的吗?”)

大家先来看两张对比的图,着一张是正确的输出结果:


再来看一张错误的输出结果:(这一个是我需要调的程序)



然后就开始要求我GF赶紧对公式,对比正确输出所用程序的代码,看看两者到底有什么地方不一样。由于两个程序所用的坐标系不一样,所以对比起来比较困难,最后费了好大的劲,把坐标系修改成完全一样的之后,发现问题依旧。这个时候另外一个现象更加困惑了我:在修改错误程序的坐标系之后,发现图形的缩小程度明显改善了,但是仍然是严重收敛的。这个现象着实打击了我一下,因为我一开始只是以为是误差量的积累造成的。难道说就是调整了一下几个公式的位置以及一些正负号就会造成误差累积量的不同?还真是前所未见的情况!
这里整个调试过程是非常痛苦的,因为总共大约有几千万次的循环,计算量之大不可想象。而输出正确和错误的程序之间,在大约每60次循环才会产生大约1x10-7细微差别。难为我GF在那里单步调试了几十万次的循环,真是可怜啊。到底是哪里出了问题呢?多亏我用VC7来运行了一遍,才发现问题所在。(之前都是我在抽空Review代码,GF在1000km+的距离以外用VC6在调试。)下面这段代码就是存在错误的地方:
void MultiMatr(int s, int n, int t, double *arr1, double *arr2, double *result)
{
    
double *tmp;

    
for (int i = 0; i < s; i++)
    
{
        
for (int j = 0; j < t; j++)
        
{
            tmp 
= result + t * i + j;
            
*tmp = 0;
            
for (int k = 0; k < n; k++)
            
{
                
*tmp += ((*(arr1 + n * i + k)) * (*(arr2 + t * k + j))); 
            }

        }

    }

}


/***************************** update ***************************/
void UpdateQ(double WnbbA[3])
{
    
int        i;
    
double    deltaSita0, angSin, angCos;
    
double    deltaSita[3], qChange[3], qTrans[4][4];

    deltaSita0 
= 0;
    
    
for (i = 0; i < 3; i++)
    
{
        deltaSita[i] 
= WnbbA[i] * quaDel;
        deltaSita0 
+= deltaSita[i] * deltaSita[i];
    }

    deltaSita0 
= sqrt(deltaSita0);

    angCos 
= cos(deltaSita0 / 2);
    
if (deltaSita0 == 0)
        angSin 
= 0.5;
    
else
        angSin 
= sin(deltaSita0 / 2.0)/deltaSita0;

    qTrans[
0][0= qTrans[1][1= qTrans[2][2= qTrans[3][3= angCos;
    qTrans[
0][1= qTrans[3][2= -(angSin * deltaSita[0]);
    qTrans[
1][0= qTrans[2][3= -qTrans[0][1];
    qTrans[
0][2= qTrans[1][3= -(angSin * deltaSita[1]);
    qTrans[
2][0= qTrans[3][1= -qTrans[0][2];
    qTrans[
0][3= qTrans[2][1= -(angSin * deltaSita[2]);
    qTrans[
3][0= qTrans[1][2= -qTrans[0][3];

    MultiMatr(
441, (double*)qTrans, (double*)q, (double*)qChange);

    
for (i = 0; i < 4; i++)
        q[i] 
= qChange[i];

}

大家看出来那里错了吗?真是稀松平常的错误啊!害死人了。

posted on 2004-09-17 00:45:00 by sumtec  评论(28) 阅读(4460)

呵呵!样机到了……

经过多天的苦等,开发样机终于到了。其实是一个比较“旧”的型号了,dopodo 535。
赶紧拿机子来玩玩,blog都不看了(先写一篇,立此存照,证明我比JGTM'2004要造一步接到手机!)
大家看我工作卖力气吧!JGTM'2004还在睡觉呢!:-D
(天晓得JGTM'2004今天早上几点钟睡的觉,这两天我到亲戚家去了……休假休假:-)   )

posted on 2004-09-15 19:49:00 by sumtec  评论(10) 阅读(1835)

即将离开南京,趁我还有点时间写点吧

人生就是这么奇妙,到处都是陷阱到处都是十字路口,走不了多久你就需要仔细思考做出选择,而平凡无忧的生活总是一个很小的片断。这一次我选择离开原来的地方,因为我太清闲了,感觉没有学到更多的东西。但是如何选择新的工作地点真是一件非常头痛的事情,可供我选择的有大中小三个方向,越大越保守,越小越有激情。其实反过来说就是越大越稳定有保障,越小越奔波冒风险。面对这样一个选择,我咨询了很多人的意见,真是什么样的说法都有,感觉就跟小学课本里面的《小马过河》一样,问了之后更加不知道自己该做什么样的决定了。折腾了一个礼拜,最后还是一位在国际大公司里面当“高层”的大朋友(没有到CXO那一种级别,估计低两到四级吧,具体我也不清楚)给我做出了很有用的分析,不过却没有给我答案,但是我听完以后我终于能够狠下决心下了那个其实我一直都想下的决定——跑去跟JGTM疯至少一阵子。也就是说,我要离开南京跑北京去了。

说老实话,我对于这样的决定也真的没有什么信心,我只是想着我在那边也许能够学到更多我希望学到的东西,这也许已经足够了。而另外一个诱惑着我的,则是看看有没有机会参加博客堂的腐败聚会,认识一下开心、mvm等重要人物。当然更重要的还是让他们认识我,如果以后又要再次寻找发展空间的时候,希望有更多的人能够给我提供帮助(当然我会很感激的啦)。嗬嗬,先不说这些了,免得JGTM说我没有诚意。其实担心还是一只存在的,因为我是一个怀疑论者,如果看不到事实就算说得多好听,我还是会怀疑的。具体一点讲,就是没有看到真正的产品被大量卖出去了、盈利了,我是不会认项目是成功的。说得更难听的就是,我从来不会认为一个产品将来一定会成功,对我来说罗列多少预测数据都没有意义。就这样一个个性,其实我会整天担心创业的项目会不会最终失败,会不会远没有我们想象的那样好。(我就见到过很多容易盲目乐观和冲动的案例,结果都不是很理想。)其实我加入JGTM所能够做到的也就是尽力做好自己的工作,努力的学习,至于产品是否成功,最终还是市场说了算,我也无能为力。

具体什么时候动身,还需要看我在南京的各项准备工作是否顺利,要处理的个人事务实在是不少,很令我头痛。但是月底之前一定是要出发了,因为房子的租期要到了。因此在这里跟cnblogs的 hBifTs 说一声抱歉,恐怕我们是无缘在南京见面了,如果您有空的话可以到北京来找我,呵呵。说到去北京,我想可能要跟曾经在我现在这个公司的,但是现在已经到了北京chinablog的一位同事碰头了,至少他也要回来南京处理一些东西,也许我们会一块出发去北京吧。在北京还可以碰到我上面提到的那位大朋友,这是一件让我感到幸福的事情,因为上次他给我提建议的时候,我就感觉到我学到了很多人生和社会方面的知识,觉得他的阅历确实非常丰富。到了北京我一定会经常找机会跟他一块喝茶,讨教一些人生的经验。(呵呵,跟高级的ID交流,打经验值,飙得狂快哦!)不过人家是在飞机上的时间多过我睡觉的时间,有没有机会就另当别论了。

最后,首先要感谢JGTM给我提供了这么一次机会,也提供给我很好的工作设备。其次要感谢这次邀请我的几家公司,虽然我的最终选择并不是你们,有一些甚至连面试都cancel掉了,虽然你们也许不会有人看到我的Post(看到的给我留个言吧,比如郭先生孙先生,好让我知道我们还是 keep in touch 的)。我希望仍然能够和你们保持良好的关系,也希望以后能够有机会合作愉快。另外还要感谢所有我请教过意见的朋友们,你们的建议对我非常重要,我想这次我能够做出很全面的分析,离不开你们的帮助,比如Henry, Montaque, dudu等,人太多了不一一数出来了。此外我也对这么多天整天烦着你们表示歉意!

这几天我也许会忙,也许会心情不好,总之如果从现在开始三十天内没有更新自己的Blog,那也是很正常的。不过我想我这个文笔糟糕,水平麻麻的ID,也不会有人跑来给我催稿的。万一我真的有几个“粉丝”想看我的Post而不得,还请多担待,多等等,谢啦!

posted on 2004-08-11 16:15:00 by sumtec  评论(28) 阅读(3946)

看!我写的关于“简单异或”加密的破解分析演示程序!

简单异或实际上是非常的危险的,这个知识是在书上看到的。最近跟某位朋友进行了这方面的争论,因此我突然对这个问题非常感兴趣。其实之前我也没有任何密码学分析的经验,更没有写过相关的程序。今天也就花了一天的时间,就把整个破解程序给写出来了。
这个是那位朋友提出来的算法的核心:
char g_szSeed[5/*26*/= 
'a''b''c' ,'1''2'
}


BOOL Compress(LPCSTR lpstrSrc, LPSTR lpstrDen, unsigned 
long lLen)
_ASSERT(lLen 
> 0); 

size_t nSeedCount 
= sizeof ( g_szSeed ) / sizeof(char); 

for(unsigned long i = 0 ; i < lLen; ++i )
char chCurSeed = g_szSeed[i % nSeedCount]; 

if(*(lpstrSrc + i)) 
*(lpstrDen + i) = (chCurSeed ^ *(lpstrSrc + i)); 
else 
*(lpstrDen + i) = *(lpstrSrc + i); 

}
 


return TRUE; 
}
 

他写的是C++代码,我对这个进行了一定的转化,变成了C#的形式。然后对这个加密算法加密出来的密文进行攻击,攻击的时候完全不知道密钥的长度及内容,也不涉及加密算法代码本身(当然会涉及到该加密算法的相关知识)。因此破解过程还是相当的公正的。

想知道我怎么进行破解的吗?点击这里可以下载源程序(当然也包括破解程序)。

运行过我的程序,你应该会发现原来破解“简单异或”加密算法是一件多么容易的事情了:一天的编码时间(从完全没有这方面经验开始),加上几秒钟都不到的运行时间,一切就搞定了。

posted on 2004-08-06 21:48:00 by sumtec  评论(11) 阅读(7331)

关于破解56位密码的时间需要花费多长?(及其他)

请允许我在这里不停的贴出有关密码学的东西,并且还都是载录自《应用密码学》这一本书当中的。因为首先我在密码学方面的知识也是相当的肤浅,我自己说出来的话必然没有什么威信。但是这本书的作者则很不一样,是这方面的专家。豆腐基于密码的安全里面提到的BlowFish加密算法就是这本书的作者Bruce Schneier所设计的。能够设计一个比较出名的,也比较安全的加密算法的人,他的话应该足够权威了。BlowFish在这本书的P237有介绍,并在本书的最后面还有源代码。
其次,这本书写得非常的好,影响也非常的大,甚至曾经遭受到NSA(也就是美国的国家安全局)的阻挠,经过很大的努力才最终发行的。这本书里面的所有数据都不是随便说说,可以说是引经据典,一共引用了1653本书或者论文等。即使你不相信Bruce Schneier的话,那也应该相信他所引用的资料,这些资料能够被引用,那我想大多数应该是一些著作或者在权威杂志发表的。

我之所以在如此短的时间之内贴出这么多的资料,主要是因为看到leighsword在我的第一篇关于密码的Post里面的回复,坚持使用异或,因此发了第二个Post。同样的原因,看到leighsword在第二篇文章里面声称56位的密钥是安全可靠的,因此不得不贴出第三篇文章。我原本想把下面这些话直接在第二个Post里面回复,但是我想可能有很多人同样不知道密钥长度的安全性问题,贴出来也算是共享知识。在这里我无意针对任何人,因为我也曾经有过同样的误解,我也曾经使用过类似异或的方法来进行数据加密。但是后来我发现错了,并且我不希望同样的错误发生在其他人的身上,以免造成损失。

下面这一端是摘录自《应用密码学》这本书(第二版)P106页下面的:

最近Micheal Wiener决定涉及一台穷举攻击机器[1597、1598]。(注:引用其他文章的内容,看来应该是真实的,或者说至少是很严肃的研究结论,而不是什么拍拍脑袋就想出来的事情)(这台机器是位攻击DES设计的,但对任何算法都适用。)他设计了专门的芯片、主板、支架。并估算了其价格。他发现只要给丁一百万美元就能够制造出一台这样的机器是其在平均3.5小时(最多不超过7小时)里能破译56-位密钥的DES算法。他还发现机器的价格和破译速度之比是成线性的,表7-1列出了各种密钥长度的对应数据。记住摩尔定律:大约每经18个月计算机的计算能力就会翻一番。这意味着每5年价格就会下降到原来的百分之十,所以在1995年所需要的一百万美元到了2000年就只用花十万美元。流水线计算机能够做得更好[724]

 

花费的金钱(美元) 密钥长度
40 56 64 80 112 128
10万 2秒 35小时 1年 70000年 1014 1019
100万 0.2秒 3.5小时 37天 7000年 1013 1018
1000万 0.02秒 21分钟 4天 700年 1012 1017
1亿 2毫秒 2分钟 9小时 70年 1011 1016
10亿 0.2毫秒 13秒 1小时 7年 1010 1015
100亿 0.02毫秒 1秒 5.4分钟 245天 109 1014
1000亿 2微秒 0.1秒 32秒 24天 108 1013
1万亿 0.2微秒 0.01秒 3秒 2.4天 107 1012
10万亿 0.02微秒 1毫秒 0.3秒 6小时 106 1011

对一个56-位密钥,穷举攻击所需金额对很多大公司和一些犯罪组织来说还是可以承受的,对于64-位密钥,则只有一些发达国家的军事预算才能够承受。而破译80-位密钥现在仍然不可行,但是如果按目前的形势继续发展下去的话,这种情况将会在30年内发生改变。
当然,估计未来35年计算机的计算能力是很可笑的,一些科幻县说理出现的技术突破可能会觉得上述预测很可笑。相反,目前一些位置的物理限制又使人们产生不切实际的乐观。在密码学中悲观一点是很明智的。用80-位密钥的加密算法是一种目光非常短浅的行为,还是坚持至少用112-位的密钥吧。
如果攻击者想要不择手段地破译一个密钥,他们必须要做的全部事情就是花钱。所以,估计一下密钥的最小“价值”似乎是明智的:在试图破译一个有经济价值的密钥之前,要确信他到底有多大价值呢?举一个极端的例子,如果一个加密的消息仅值1.39美元,那么用一台价值1000万美元的破译机来寻找它的密钥在经济上就毫无意义了,另一方面,如果明文消息值1亿美元,那么早已太破译击破一次信息是值得的。此外,有些消息的价值会随时间迅速减少。

其实我也并不是所有的东西都记得,只是有一些很经典的话我是记得非常清楚的,就像上面的那一段话。这段话里面包含了非常有价值的信息在里面:
1、我们应该怎样选择密钥的长度?
上面的那个表充分说明了解答这个问题的关键。这个表的数据是1995年的数据,现在已经过去了将近10年了,也就是说上面的金钱花费已经严重缩水到原数值的1%,第一行的数据实际上应该是一台造价为1000美元的机器,约合人民币8000元。我想如果用普通的8000元人民币的PC机,假设其计算性能也许只有文中所述的破译机的千分之一,那么35000小时也就是1458天约合4年不到,也绝对不是LeighSword所说的1万年都解不出来。实际上的数字应该比这个悲观不少,我们可以看看2002年11月8日的新闻,里面说到破解109位密码竟要劳驾1万台PC花费549天。看起来好像挺悲观的但是实际上你会发现,原来单台PC破解109位密码的能力也就需要549万天,约合15041年多一点。对照上表,可以发现这个数值比目前一台8000元人民币的PC暴力破解80位DES的时间还要短得多!当然,这里面的破解方法并不一定是纯暴力破解,而且对方所使用的是什么算法也不清楚。但是由于基本上可以猜测这是一个基于暴力破解的破解方法,而暴力破解对于到底是什么算法敏感性比较低,所以可以从一个侧面反映上表的估计还是八九不离十的。也就是说在今天,对于一个56位的密码用一台普通的8000元人民币的PC,暴力破解的时间应该在几小时到几个月之间,至于是多少我也不清楚,但是我想这个估计还是比较合理的。
现在我们已经知道了,如果你需要对你的秘密进行保密的话,那最好还是相信上表的内容,甚至应该乘以一定的安全系数。上面那一段话也提到了,选择多长的密钥取决于你的信息的价值,没有人会为了一个可能只有1美元左右价值的信息去花费超过1美元来进行破解的,因为这样明显不值得。但是大家也不要误解了上面的那一段话,因为一台价值1000万美元的机器,其每次解密的成本并不是1000万美元。如果算上运行费用,假设保费之前能够进行10万次解密,那么每一次解密的成本也许就是300元。如果更加精确一点的计算应该是按照时间来衡量的,按照05年计算成本来计算(相当于95年10亿美元的机器)解密56位密钥的密文,如果这台电脑能够连续用一年的时间,那么一共可以解大约242.6万次,那么每次的成本也就是15美元左右。假如一个网站用56位的密码保存有关如何获取一台笔记本奖品的信息,那么显然我愿意去花这15美元,甚至多花十倍的价钱都是物超所值的。
照这么说,我应该如何决定密钥的长度呢?密钥的长度应该是越大越好!如果你的软硬件允许,就应该使用128位的密钥。实际上加密的成本是低之又低,速度是快之又快,我相信现在随便哪个人的电脑都能够承受128位密钥的对称加密算法的加/解密运算,并且我认为你几乎就感觉不到56位和128位在无论是速度还是成本上到底有什么差别。那么你为什么不用128位密钥而用56位呢?解释就是你没有意识到上面我说的这段话,或者是你懒,或者是这个东西其实根本就不值得加密,明文密文都无所谓,你只想不让你妹妹看到你的情书面子上挂不住而已。希望看到我这一段话之后,都会有一个正确的认识。
2、如何选择加密算法?
实际上我不知道大家意识到没有?我在上一个Post里面已经摘录了一段话,其大意就是:算法是否安全必须通过公开的检验才能够断定,如果你的安全性是根据别人不知道你的算法这个假设的话,绝大多数都是一个非常危险的假设。RC4就犯了这样的错误,如果说一个专业设计密码的人都会在这个问题上面栽跟头,您还是不要盲目相信自己的实力了。
目前来说,有好多算法是非常安全的,当然可能代码来说是比较复杂一点,但是有很多免费的库可以提供这些能力(部分算法不是免费的),而很多的开发环境比如.NET Framework甚至就直接提供各种很好的加密算法。就算如果不能够使用这些既有的资源,必须自己编写代码或者使用别人的代码,那也千万不要选择异或这样的算法,非常地不安全。这里需要稍微详细说一下各种的密码学分析:
a. 暴力破解。这是最为原始的分析方法,可以说是性能上非常糟糕一种方法,大部分的分析方法都有机会比这个方法更加有效,但是也有很多分析方法在特定的条件下甚至能够比这个方法更糟糕。但是从另外一个方面说,这个分析方法跟加密算法本身的强度的敏感性十分的低。如果一个加密算法通过暴力破解需要时间T,那么同等密钥长度的另外一个算法,其破解时间也应该跟T相差不远,至少不是十万八千里的。上面那个表的数据就是暴力破解的数据,而一个好的加密算法应该使之能够通过暴力破解来进行分析的。但是这句话千万不要反过来理解,认为任何加密算法的安全强度都能够对照上表来估计,那就大错特错了,因为还有很多的密码学分析方法,而大部分其他密码学分析方法所需要的时间在特定条件下都会远远小于暴力破解所需要的时间。之所以说异或是很糟糕的方法,是因为他能够通过其他分析方法来达到用远远小于T的时间来破解的。
b.逆向工程法。这也是一种大家都能够想到的方法,意思就是我有你的算法的源代码,据此分析出解密的函数D或者替代函数D'。需要说明的是,不一定能够直接得出一个结论,也许是通过分析源代码得出这个算法的弱点,或者密钥信息泄露的途径。如果拥有源代码,并且分析出密钥信息泄露的途径,那么很明显可以通过选择明文攻击的方式来获得完整的密钥。比如密钥的某一位或者某几位会反映在密文的某一位或者某几位上面,那么可以通过设置一组特定的明文来获得密钥的一部分,多组明文就能够恢复密钥。如果你寄希望于直接获得解密过程,那么这个方法也不见得是一种好的方法,肯能会使一件很困难的事情。尤其对于那些非常健壮的算法来说,例如DES等等,这些算法完全就是公开的,目前根本就没有能够直接获得解密过程的方法,甚至连非常有效的选择明文攻击都没有。好的加密算法显然也应该能够经受这种分析。
c.其他各类统计学方法。例如前面提到的重合码计数法,以及没有提到过的线性攻击和差分攻击。实际上这些都是基于有选择性的明文或者密文攻击的,攻击的方法就是统计这些数据的特征,试图找出密钥的长度、密钥特征等信息,一次缩小穷举搜索的范围,甚至直接组合出整个密钥。比如说异或算法,其实上一个Post已经说到了整个的破解过程,我在这里再稍微解释一下:
1、首先由于密钥的长度是有限的,如果攻击时所使用的位移长度和密钥长度一致,则可能泄露一定的信息。也许这些信息不完整,对于知道整个密钥的信息没有什么帮助,但是却可以知道密钥的长度。
2、如果已经知道密钥的长度了,那么把密文和位移了密钥长度的密文相异或,就能够消除密钥,得到明文间的异或。这个时候由于已经没有密钥存在,因此就可能分析出整个的明文信息,并据此得到密钥。

实际上我看到LeighSword的另一个回复,似乎提到了使用随机数。但是实际上如果不是用于密钥交换,那么就必然不能够使用真正的随机数,而只能够通过随机数发生器来产生,而这个时候算法的强度则还需要看这个随机数发生器的强度。之所以不能够用真正的随机数,是因为需要重复这个过程进行验证,无论是通过解密来验证,还是通过再次加密比较密文来验证,都需要这个随机数严格一致。这个时候实际上已经是加密算法的一部分了,实际上绝大多数的加密算法里面都用到了随机数发生器以及异或运算。也许我说得不清楚,上面提到的不安全的是简单异或算法。如果LeighSword用到了随机数发生器,那么就不能够说是简单异或算法了。一般说“异或加密”意思就是仅仅利用了异或操作,或者简单的叠加上轮换或者替换方法,并且只有一轮操作。如果加上了随机数发生器,那么就不能够随便地称之为“异或加密”算法了。

一般比较成熟的加密算法都是采用下述操作进行组合:
1、异或
2、循环位移
3、S-盒(类似的东西)
4、交换(某一位或者几位)
5、多项式计算(比较少见)
以上述的操作组合成为一个标准的加/解密“轮”,然后将这个“轮”进行多次串联来产生最终输出,所以一般我们都会看到很多地方会说DES最好至少采用16轮以上的加密,就是这个意思。轮数越多,就越有可能抵抗线性攻击和差分攻击(但是也要视具体的算法而定)。如果仅仅只有一轮的算法,多数是逃不过差分攻击的,甚至连线性攻击都抵抗不了。那么是否抵抗线性分析和差分分析是否那么重要呢?我们来看一下《应用密码学》P206下面的一段话:

……。Susan Langford和Hellman对一个8-轮DES进行攻击,选择明文数为512时,会付出10密钥位的可能性为80%;选择明文数为768时,会付出10密钥位的可能性为95%。在上述攻击进行后,再采用穷举搜索得到剩余的密钥空间(246可能密钥)。……。然而,对更多轮数的DES,这种扩展似乎也不易实现。(注:这里所说的DES的密钥长度是56位)

换句话说,如果你的加密算法不能够抵抗一些密码学的分析,那么实际上你的“有效”密钥长度并没有你所设置的那么长。如果我们对照上表,那么也许你就会发现,也许原来你以为你的数据经过加密之后其有效保密时间至少是35小时,但是实际上却只有几十秒钟的有效时间。当然,上表的数据应该是一个标准的DES,有16轮的加密过程,而上面所说的攻击是针对8轮DES而言的,对于16轮的DES,也许效果就不是那么明显了。但是如果你的加密算法只有1轮,那么问题肯定会非常的严重!设计一个加密算法远比我们想象的要复杂和危险,就如书中所说的那样,宣称它是不安全的比证明他是安全的要容易得多。

关于某个特定的加密算法的争论,我并不想争论下去。在这里我也只是尽我所能,把我所看到的一些书上面的文字共享出来,希望都能够对密码学有稍微深入一点的了解。

这篇文章本来应该昨天下午就Post出来,结果上海突然有一个完全不认识的人打电话过来问我上海HP去不去(可能就是去当个小程序员),只好赶紧跟对方联系,又是打电话发邮件,又是准备资料的,忙了一个下午,晚上还要打电话给家里人商量……

posted on 2004-08-06 09:35:00 by sumtec  评论(32) 阅读(7968)

还是有人坚持使用异或加密,不得已在摘录一段话

还是从《应用密码学当》中节录下来的一段话(P10-P11):

这是一个对称算法。明文用一个关键字做异或运算以产生密文。因为用同一只取一或两次就会付出原来的值,所以加密盒解密都严格采用同一个程序。
这种方法没有实际的保密性,它易于破译,甚至没有计算机也能破译,如果用计算机则只需花费几秒钟的时间就可破译。
假设明文是英文,而且假设密钥长度是一个任意小的字节数,下面是他的破译方法:
1、用重合码计数法(counting coincidence)找出密钥长度。用密文异或相对其本身的各种字节的位移,统计那些相等的字节。如果位移是密钥长度的倍数,那么超过6%的字节将是相等的,如果不是,则至多只有0.4%的字节是相等的(这里假设用一随机密钥来加密标准ASCII文本;其他类型的明文将有不同的数值),这叫做重合指数(index of coincidence)。指出密钥长度倍数的最小位移即密钥的长度。
2、按此长度移动密文,并且和自身异或。这样就消除了密钥,留下明文和移动了密钥长度的明文的异或。由于英语每字节有1.3位的实际信息(参见11.1节),因此有足够的冗余度去确定位移的解密。
尽管如此,一些软件销售商在兜售这种游戏式算法时,还声称“几乎和DES一样保密”,这使人感到震惊。NSA最终允许美国的数字蜂窝电话产业界使用这个算法(有160位的重复“密钥”)对语音保密。异或或许能防止你的小妹妹偷看你的文件,但却不能防止密码分析家在几分钟内破译它。

可以这么认为,如果你用异或进行加解密,那么跟直接保存明文就没有什么差别。因为一旦取得了密文,并且知道使用的是异或算法,那么剩下来的保密时间就在几秒钟到几小时之内。即使一个没有什么密码学知识的人,也可能写出一个什么工具来进行破解计算。或者说你如果采取了异或加密算法,那么整个系统的安全性就根本不在你手中,那么你加上这个算法和不加上又有什么区别呢?干脆不要加算了。

posted on 2004-08-05 12:24:00 by sumtec  评论(44) 阅读(10240)

关于密码的问题

前一阵子看到豆腐基于密码的安全,很多人都在里面进行了讨论,这让我想起来那本我一直很推崇的书《应用密码学》。我记得在以前其它的Blog上面也提到过,甚至可能写了几乎完全相同的内容。不过在博客堂我没有写过类似的内容,在这里再写一遍吧。

我们平常经常都会涉及到加密、解密、签名以及验证等问题,这些都跟密码有关系。密码是一种学问,里面包含了很多的东西。如果我们看到上面那四个问题,我们固然会想到加密算法,比如RSA,DES,BlowFish。所谓加密算法无非就是怎样用一套称为密钥(包含非对称算法的公钥)的东西,将某些信息颠来倒去的过程。这个过程看似神秘,但是实际上这个并不是密码学里面发挥关键作用的东西。当然,算法不好,那么可能很容易通过一些方法进行破解,算法好则相对困难。那么什么是更关键的呢?下面这一大段话则是摘录自《应用密码学》一书第4页:

 

常用的密码分析共计有四类,当然,每一类都假设密码分析者知道所用的加密算法的全部知识:


1、唯密文攻击(ciphertext-only attack)。密码分析者有一些消息密文,这些消息都用同一加密算法加密。密码分析者的任务是恢复尽可能多的明文,或者最好是能推算出加密消息的密钥来,以便可采用相同的密钥解算出其它被加密的消息。……
2、已知密文攻击(known-plaintext attack)。密码分析者不仅可以得到一些消息的密文,而且也知道这些消息的明文。分析者的任务就是用加密信息推出用来加密的密钥或者到处一个算法,此算法可以对用同一密钥加密的任何新的消息进行解密。……
3、选择明文攻击(chosen-plaintext attack)。分析者不仅可得到一些消息的密文和相应的明文,而且他们也可选择被加密的明文。这闭一只明文攻击更有效。因为密码分析者能选择特定的明文块去加密,那这些块可能产生更多关于密钥的信息,分析着的任务是推出用来加密消息的密钥或者到处一个算法,此算法可以推用同一密钥加密的任何新的消息进行解密。……
4、自适应选择明文攻击(adaptive-chosen-plaintext attack)。这是选择明文攻击的特殊情况。密码分析者不仅能选择被加密的密文,而且也能给予以前加密的结果修正这个选择。在选取较小的明文块,然后再基于第一块的结果选择另一明文块,以此类推。……

另外还有至少三类其它的密码分析攻击。

5、选择密文攻击(chosen-ciphertext attack)。密码分析者能选择不同的被加密的密文,并可得到对应的解密的明文,例如密码分析者春去一个防篡改的自动解密盒,密码分析者的任务是推出密钥。……。这种攻击主要用于公开密钥算法,……。选择密文攻击有时也可有效的用于对称算法(有时选择明文攻击和选择密文攻击一起称作选择文本攻击(chosen-text attack))。
(注:稍微解释一下,这个攻击的前提是分析者能够获得一个密封的“解密盒”,也就是一个已经固化的、专门用于对用某一个特定密钥加密过的密文进行解密的硬件。攻击的方法就是随机产生一个“伪密文”(不一定是合法的),让解密盒进行解密,从所得到的明文和密文进行比较,得到关于密钥或者算法的相关信息。这种攻击实际上和选择明文攻击相类似(就是它的逆过程),只是明文变成密文肯定能够成功,但是逆过程则不一定成功。同时,一般加密算法的设计对于从加密后的密文里面泄露密钥信息是比较注意的,但是从明文里面泄露消息则考虑得相对较少。此外,如果是非对称加密算法,两个破解方向由于密钥长度的不同,会引起破解难度的巨大差别。因此选择密文攻击很可能得到比选择明文攻击更多的信息。)
6、选择密钥攻击(chosen-key attack)。这种攻击并不表示密码分析者能够选择密钥,它只表示密码分析者具有不同密钥之间的关系的有关知识。这种方法有点奇特和晦涩,不是很实际,……。
7、软磨硬泡攻击(Rubber-hose cryptananlysis)。密码分析者威胁、勒索,或者折磨某人,直到它给出密钥位置。行贿有时称为购买密钥攻击(purchase-key attack)。这些是非常有效的攻击,并且经常是破译算法的最好途径。

已知明文攻击和选择明文攻击比你想象的更常见。密码分析者得到加密的明文消息或者贿赂某人去加密锁选择的消息,这种事情时有所闻。如果你给某大使一则消息,你可能会发现该消息已被加密,并送回他的国家去研究。……。已知明文攻击(甚至选择明文攻击)在第二次世界大战中已被成功地用来破译德国和日本的密码。……

 

看到这里大家也许就会发现了,这里根本就没有讨论到具体某个加密算法。并且可以看到,越后面的攻击对于安全的危害性越大,而跟具体加密算法的强度的关系就越小。换句话说,整个系统的信息安全程度在很大程度上取决于与具体加密算法算法无关的部分。那么这些部分是什么呢?是协议。

协议是一套过程——比如保管密钥和密文的方法,或者交换密文信息或者密钥的步骤等等。协议的内容不一定全部都是和算法或者计算机内部相关的内容,有时候也包含了自然人如何能够接近甚至得到操作的机会或者其它的一些现实当中的事情。如果协议设计得不好的话,将会比较容易受到2-7的攻击,这个时候就不一定取决于加密算法的强度了。就像豆腐基于密码的安全里面提到的攻击,可以认为是3+7的一种混合攻击:首先通过7得到了数据库的访问和修改权限,其次通过3得到了一个已知明文的合法密文,然后修改数据库使得超级用户的密码是自己设定的密码。这里的选择明文攻击根本就不关心具体的密钥是什么,只要得到合法的密文就足够了。当然,如果作者有足够的知识和时间,完全可以破解出这个密钥出来,日后可以随时进行直接的攻击。其实在这本书里面有很多很有趣的例子,说明了协议在密码学里面是多么重要,如果有时间我在节选一下这本书里面的例子,给大家参考参考。

最后我再节选出该书当中对我有“开窍”作用的那么一段话,在第5页下面:

不要忘记Kerckhoffs的假设:如果你的信的密码系统的强度依赖于攻击这不知道算法的内部机理,你注定会失败。如果你相信保持算法的内部秘密避让研究团体公开分析它更能改进密码系统的安全性,那你就错了。如果你认为别人不能返回便溺的代码和你想设计你的算法,那你就太天真了(1994年RC4算法就发生了这种情况——参见17.1节)。最好的算法是那些已经公开的,并经过世界上最好的密码分析家们多年的攻击,但还是不能破译的算法(国家安全局对外保持他们算法的秘密,但他们有世界上最好的密码分析家在内部工作,你却没有。另外,他们互相讨论算法,通过执着的审查已发现工作中的弱点)。

也就是说,我们整个系统的强度应该是假设除了未加密的密钥之外,完全暴露在外界当中的情况下的强度。比如说豆腐基于密码的安全里面提到用用户名作为salt,实际上对于加强整个系统强度的帮助可能是有限的:
1、假如取得数据库的权限相当于取得系统的执行权限甚至调试权限,那么完全有可能通过类似调试的手段手动调用系统的“加密”部分的函数,得到密文结果。
2、或者如果我们得不到这个执行的权限,也可以通过选择明文攻击的方法来进行的破解,就是多注册几个不同的用户,密码一样,找出salt对于最终结果作用的关系。

当然,上面这个想法只是随便想想的,也许实际上也没有更好的办法。我的意思是考虑安全问题的时候如果焦点在算法安全性,或者系统的保密能力上面,那就错了。

posted on 2004-08-05 11:30:00 by sumtec  评论(7) 阅读(3817)

关于.NET的两道题目

1.   The only references that an interface provides:
 
 a.  are declarations of functions only

 
 b.  are declarations of fields only

 
 c.  are declarations of methods only

 

2.   All interface methods are …….. by definition.
 
 a.  Private

 
 b.  Public

 
 c.  Internal

 
 d.  Protected

 

我没有答案,各抒己见吧。

posted on 2004-08-04 11:08:00 by sumtec  评论(8) 阅读(1572)

难道我的英文真的很差?

最近我同事的朋友替公司做题目,这个题目是网上的,好像是一个什么Symbol公司出的题,是Symbol认证。因为这些题目都是关于.NET方面的,所以我同事让我帮她的朋友做。可是这些题目实在是太难了,我给一个比较经典的吧:

What’s true about types in C#?

a.

The CTS only appropriate operations can be performed on a particular type

b.

The program will not compile

c.

The program will cause run-time error

d.

Every type in CTS is controlled

e.

A&B

f.

A&B&C

g.

A&B&D

h.

A&D

i.

B&C

可惜我是丈二金刚摸不着头脑,types in C# 和 The program will not compile 有什么关系呢?注意这里没有任何的上下文,types in C# 不知道具体指的是哪一个范畴的,program也不知道是什么东西。更可怕的是,我觉得这里夹杂着一大堆的语法错误,我根本就看不懂。就像这里所说的program will not compile,感觉program是主语,也就是说program应该是指cs.exe这个compiler。那么宾语又是什么?

还没有看完这一份卷子,我就已经晕掉了。还有类似什么:

Which of the following is not a Boxing and unboxing rule?

a.

An object can only be accessed in C# by its interface.

b.

The interface defines the rules how it can be accessed.

c.

The System.Object base class interface only accepts reference types.

d.

The System.Object base class interface accepts all available types of the CTS.

e.

Any variable of type value has to be converted to type reference. This process is called BOXING.

f.

Boxing happens automatically

 

大家说说什么是System.Object base class interface?四个名词连在一起的效果就像我说“飞机花朵骨头云只能够看”一样,不知道是什么意思。难道应该有逗号在这几个词当中?也不像啊?也许这里的base是形容词,可还是看不懂什么叫做class interface。谁看得懂的教教我,说不定是我太长时间没有接触英语退化了。

还有下面这个题目也让我觉得很模棱两可:

Which of the following languages support objects?
 
 a.  C++

 
 b.  Microsoft Visual Basic

 
 c.  C#

 
 d.  A&B

 
 e.  A&B&C

 
 f.  A&C

 
 g.  No answer is correct

严格的说VB不支持OO,那是否supports objects就值得商酌了。大家觉得应该选择 e 还是 f 呢?

posted on 2004-07-30 14:41:00 by sumtec  评论(12) 阅读(2050)

Hey, everybody!

今天有一位MVP朋友问我是否想做MVP,我想了半天,还是觉得有机会就要尝试,失败了也没什么大不了的。所以最后决定要参加这么一次活动,虽然是自不量力,也要搏一搏啦!

如果说大家都能够来推荐我一下多好啊,可惜只能够由MVP来推荐。目前有两位MVP朋友推荐我,我已经感到非常的高兴了,但是我这个人不容易满足,所以特地来做一下广告,推销一下自己,看看会不会有其他MVP也来推荐我呢?

先来一个三句话的简短介绍:
1、我叫郑毅帆。
2、我之所以有勇气参选MVP,是因为我在.NET CF方面有一定的经验。
3、我参选MVP的目的是推销自己,如果当选了我一定发扬乐于助人的精神。

下面是我在MVP申请表格里面填写的自我简介:

大家好,我是郑毅帆,英文代号sumtec。无论在哪里看到sumtec,那么多半就是我本人了,尤其在中文网站里面。"Sum" for summary and "tec" for technology. Sumtec是我在初二的时候给自己命名的“代号”,为什么说是代号呢?因为这不是一个英文的人名,没有人叫这样奇怪的名字,不过我个人很喜欢这个代号。

在过去的一年多时间里面,由于公司开发一个PDA上面的行业应用,而我在这一家处于创业阶段的公司里面任研发部主管,因此该任务由我来负责。在进行一轮比较之后,操作系统决定选用PPC系列,并且用.NET CF进行开发。该方案的好处是,在PPC2k2到PPC2k3之间能够进行完全无缝的“升级”,有利于日后选择不同厂家的硬件,使得我们在选择上游厂家的时候,处于更有利的地位。在几个月之前该项目的开发已经完成,目前已经转入市场销售阶段。在整个开发过程当中,对于.NET CF的不少细节问题都有了比较深入的了解。例如在SP2之前,应用程序启动速度比较慢,这是由于.NET CF设计疏漏造成的效率问题。而这个问题可以通过将部分源代码修改成另外一种等价形式来解决,但是手动修改任务非常繁重,为此我还专门开发了一个自动修改源代码的工具,用于专门解决这一个问题。

当然,我在接触.NET CF之前,对于.NET也已经非常的熟悉了。跟.NET的接触可以说是从VS2k2的Alpha版就开始了,当时由于国外黑客泄露了一份Alpha版,有幸接触到这个产品。但正是接触是在Beta1开始的,甚至在这个版本上面已经写了不少个人的应用(非商业的),因此当年在CSDN上面解答其他人问题的时候,经常能够判断出别人使用的书籍是根据Beta1版本来编写的,标志就是某些命名空间有区别,例如Winform这个命名空间。

而更早之前则是使用的QB/VB系列,这些工具时常能勾起我往事的回忆。我总难以忘怀用QBX开发一个“淡入淡出”效果的库,更难以忘记当年试图在QB上面模拟消息机制以及Windows那样的UI。不过我这个人对于不常使用的东西忘记得也特别快,以便于记住最新的知识。因此如果你现在问我VB的问题,那么恐怕我已经不能够给你很精确的答案了。VB至少有四五年没有使用了,QB就更不要提了。

大家也许发现了,我从很早之前就已经开始学习编写计算机程序了。确切的说,我是从小学4年级下学期的时候就开始了这个漫长的计算机学习历程。并且在中学的时候参加了NOI,也就是全国奥林匹克信息学竞赛,除了第一次拿了市三等奖之外,每次都拿到市一等奖,甚至有省一等以及全国一等。不过这些都是分区联赛的成绩,而说到竞选省队参加全国决赛则一次都没有,每次都是差一名进不去。我对这个感到些许遗憾,但是并不后悔,因为那是我的性格使然——我对于不解决实际问题的东西非常不感兴趣,竞选之前不愿意做充分的准备也就是一件必然的事情了。

上面提到了CSDN,这个社区什么时候加入的我都很模糊了,大概是在2000年左右吧。后来还申请当上了VB.NET的版主,为很多朋友解答过不少问题。到目前为止我在CSDN上面已经累积到15112分的专家分,其中14486分都是属于.NET板块的记分。当然这个分数并不高,想比许多高手,我这个分数也许只有几分之一到几十分之一,但至少表明我也帮助过不少的朋友们。更何况我对于分数这样的东西并不在意,能帮助别人才是最重要的。不过最近到CSDN上面的次数已经比较少了,因为我最近有一些私人事务需要处理,此外还着迷于另外一种媒体——Blog。现在维护着两个个人的Blog——http://blog.joycode.com/sumtec以及http://www.cnblogs.com/sumtec。这两个Blog实际上内容基本上一致,因为有幸受到双方的邀请,所以两边都留下来了。

说到Blog,其实这也是一个能够帮助别人的地方。把自己的心得体会写下来,供他人参考,有时候比回答别人的问题更加有效果,因为回答问题的方式也许只有提问的人才能够得到答案,但是在Blog上面所有对他感兴趣的人都能够获得满意的答案。我个人就在blog上面得到了很多帮助,同时现在我也在尽量利用Blog记录下个人的一些经验知识以及成果,希望能够帮助其他人。欢迎大家经常光顾我个人的Blog,并提出您宝贵的建议。对于我个人来说,是否能够当上MVP并不重要,我更希望能够通过这次活动展现自我。当然,如果能够当选,我会感到无限荣幸。谢谢大家对我的支持!

posted on 2004-07-29 15:21:00 by sumtec  评论(23) 阅读(1796)

对博客堂的几点建 :P

如果可能的话:

1、页面上应该显示阅读次数,好跟别人比较一下,看看自己的差距在哪里。

2、那个自动转变表情的功能是不是可以关掉?感觉有点不方便,经常在贴代码的时候会被自动转换成一个笑脸,一瓶啤酒,只好到Html里面修改,非常不方便。

3、管理页面的“随笔”、“文章”和“反馈”等,应该能够点击标题,直接进入该页面,例如:

吊胃口 III (关键词:正则表达式,正则表达式构造器,保证精彩!) True 1 1 查看 修改 删除

这样发布/修改好了,可以直接点击进去看看效果,或者直接从“反馈”那个页面,点击想要回应的回复标题,就可以进入相应的Post直接回复,等等。

4、是不是可以增加一个限制文章长度的功能,太长了部显示在首页,只显示一个“详情点击查看”的超链接,大多数的超长Post都不会写摘要的,懒惰是Developer的天性。

5、登录的时候,可不可以直接按回车进去啊。现在的方法要多按一下TAB或者用鼠标,不太符合习惯。

6、管理页面最上面那个.TEXT的图标是不是可以换成博客堂的?链接也接到博客堂的首页吧!不然从管理界面想要到博客堂首页,中间要经过一个自己的首页才能到达(或者手动在地址栏里面填写),哎呀,没办法,懒是我们的天性啊。

我也是随便说说的,老大抽空升个级已经不容易了,上面那些简直就是奢求啊,忙的话就算了。本来我想回复到开心的那个提问题的Post里面去的,可是那里面似乎都是类似Bug之类的东西,好像有点不搭界……

posted on 2004-07-21 13:59:00 by sumtec  评论(1) 阅读(1306)

【第1页/共2页,18条】
首页
前页
1

Powered by: Joycode.MVC引擎 0.5.2.0