天鹅湖边鸟飞绝,良无一点双人行.
双木非林心相连,您若无心先自飞.

导航

<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

  • 随笔 - 30
  • 文章 - 53
  • 评论 - 82
  • 跟踪 - 0

公告

Welcome Back to CommanSource

文章分类

档案

随笔分类

相册

多媒体

WEB LINK

登录

    帐号
    密码
    记住我:
     

2005年8月8日 #

 

  送给老婆的七夕礼物

 

Miss You Much!I will love you as long as i live.

 

19:21 | 评论 (6)

2004年12月3日 #

 

  Macromedia XML News Aggregator Web Service Sample Application and Source File

MXNA,Macromedia的RIA很不错的B/S升级方案。

http://www.macromedia.com/devnet/mx/flash/articles/mxna_sample.html

 

16:06 | 评论 (0)

2004年11月9日 #

 

  关于笔试的心得!

在招聘软件类研发人员的笔试中,大多数公司都会选择考IQ、EQ、C/C++、JAVA、网络编程、计算机组成原理、汇编等。但是考的最多的就是C/C++了,而且有些还非常难。

这里推荐大家看一本书《C++ 高效编程:内存与性能优化》,里面的知识点在很多场笔试中被考到。对于不太熟悉C++内存与性能优化的朋友也可以作为一种补充。

 

 

16:05 | 评论 (3)

 

  我回来啦!

这里的兄弟姐妹们都过的好吧!

唉,没有更新BLOG已经很久了,一直忙着比赛和找工作,此中酸苦更与谁人述啊......

头发又白了不少,不过还好嘛,两件事情都完美的结束了。

作诗一首,感慨万千啊

南山云,北山雾。
脉脉不知渔樵苦。
一点梅,十年树。
梦凝霜结青石路。
长灯里,短栏处。
可堪寂寞凭晓暮。
绿绮老,兰田故。
惯是沉吟比孤独。
游兮君,隐兮吾。
连环既解心何如。
看春来,听春去。
笑它东风也不悟。

一、电子科技大学'校友杯'软件开发大赛

http://202.115.22.10/news/article.php?articleid=2089

凭借基于组件的并行计算平台获得了一等奖和单项最佳设计奖.(^^!)

功能说明:电子科技大学“校友杯”软件开发大赛参赛项目.由于缺乏实验环境和机器设备,我们普通人很难研究并行算法,即使有了想法也同样面临着无法验证的尴尬。不过,在.NET Remoting的支持下,我们利用.NET在基于组件编程上的优势,来实现一个基于网络组件的并行计算平台”Hailstorm”HailStorm是一个基于网络组件的并行计算平台,用户只要按照系统提供的接口和并行计算的要求编写出.NET组件,实现自定义的并行计算.应用领域;网络安全、暴力破解、科学计算。

二、签约联想上海移动通信研发中心

做手机嵌入式开发,哇哇哇,只知道一些皮毛。努力学习symbian and arm7。

 

15:19 | 评论 (0)

2004年9月24日 #

 

  计算几何的常用算法

 

1. 矢量减法


设二维矢量 P = (x1,y1) ,Q = (x2,y2)
则矢量减法定义为: P - Q = ( x1 - x2 , y1 - y2 )
显然有性质 P - Q = - ( Q - P )
如不加说明,下面所有的点都看作矢量,两点的减法就是矢量相减;


2.矢量叉积


设矢量P = (x1,y1) ,Q = (x2,y2)
则矢量叉积定义为:  P × Q = x1*y2 - x2*y1   得到的是一个标量
显然有性质 P × Q = - ( Q × P )   P × ( - Q ) = - ( P × Q )
如不加说明,下面所有的点都看作矢量,点的乘法看作矢量叉积;

叉乘的重要性质:

        > 若 P × Q  > 0 ,  则P 在Q的顺时针方向
        > 若 P × Q  < 0 ,  则P 在Q的逆时针方向
        > 若 P × Q  = 0 ,  则P 与Q共线,但可能同向也可能反向


3.判断点在线段上


设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:

( Q - P1 ) × ( P2 - P1 ) = 0  且 Q 在以 P1,P2为对角顶点的矩形内


4.判断两线段是否相交


我们分两步确定两条线段是否相交:

(1).   快速排斥试验

设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果
R和T不相交,显然两线段不会相交;

(2).   跨立试验

如果两线段相交,则两线段必然相互跨立对方,如图1所示。在图1中,P1P2跨立
Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即
( P1 - Q1 ) × ( Q2 - Q1 )  *  ( P2 - Q1 ) × ( Q2 - Q1 )  <  0
上式可改写成
   ( P1 - Q1 ) × ( Q2 - Q1 )  *  ( Q2 - Q1 ) × ( P2 - Q1 )  >  0
当( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明( P1 - Q1 ) 和 ( Q2 - Q1 )共线,
但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,
( Q2 - Q1 ) ×( P2 - Q1 )  = 0 说明 P2 一定在线段 Q1Q2上。

所以判断P1P2跨立Q1Q2的依据是:

( P1 - Q1 ) × ( Q2 - Q1 )  *  ( Q2 - Q1 ) × ( P2 - Q1 )  ≥  0

同理判断Q1Q2跨立P1P2的依据是:

( Q1 - P1 ) × ( P2 - P1 )  *  ( P2 - P1 ) × ( Q2 - P1 )  ≥  0

至此已经完全解决判断线段是否相交的问题。


5.判断线段和直线是否相交


如果线段 P1P2和直线Q1Q2相交,则P1P2跨立Q1Q2,即:

( P1 - Q1 ) × ( Q2 - Q1 )  *  ( Q2 - Q1 ) × ( P2 - Q1 )  ≥  0


6.判断矩形是否包含点


只要判断该点的横坐标和纵坐标是否夹在矩形的左右边和上下边之间。

6.判断线段、折线、多边形是否在矩形中

因为矩形是个凸集,所以只要判断所有端点是否都在矩形中就可以了。

7.判断矩形是否在矩形中

只要比较左右边界和上下边界就可以了。

8.判断圆是否在矩形中

圆在矩形中的充要条件是:圆心在矩形中且圆的半径小于等于圆心到矩形四边的距
离的最小值。

9.判断点是否在多边形中

以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多
边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的
时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所
以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话
P在多边形外。

但是有些特殊情况要加以考虑。如果L和多边形的顶点相交,有些情况下交点只能
计算一个,有些情况下交点不应被计算(自己画个图就明白了);如果L和多边形
的一条边重合,这条边应该被忽略不计。为了统一起见,我们在计算射线L和多边
形的交点的时候,1。对于多边形的水平边不作考虑;2。对于多边形的顶点和L相
交的情况,如果该顶点是其所属的边上纵坐标较大的顶点,则计数,否则忽略;
3。对于P在多边形边上的情形,直接可判断P属于多边行。由此得出算法的伪代码
如下:


1. count ← 0;
2. 以P为端点,作从右向左的射线L;
3. for 多边形的每条边s
4.   do if P在边s上
5.          then return true;
6.      if s不是水平的
7.          then if s的一个端点在L上且该端点是s两端点中纵坐标较大的端点
9.                  then count ← count+1
10.              else if s和L相交
11.                 then count ← count+1;
12. if count mod 2 = 1
13.   then return true
14.   else return false;

其中做射线L的方法是:设P'的纵坐标和P相同,横坐标为正无穷大(很大的一个正
数),则P和P'就确定了射线L。这个算法的复杂度为O(n)。


10.判断线段是否在多边形内

线段在多边形内的一个必要条件是线段的两个端点都在多边形内;

如果线段和多边形的某条边内交(两线段内交是指两线段相交且交点不在两线段的
端点),因为多边形的边的左右两侧分属多边形内外不同部分,所以线段一定会有
一部分在多边形外。于是我们得到线段在多边形内的第二个必要条件:线段和多边
形的所有边都不内交;

线段和多边形交于线段的两端点并不会影响线段是否在多边形内;但是如果多边形
的某个顶点和线段相交,还必须判断两相邻交点之间的线段是否包含与多边形内部。
因此我们可以先求出所有和线段相交的多边形的顶点,然后按照X-Y坐标排序,这样
相邻的两个点就是在线段上相邻的两交点,如果任意相邻两点的中点也在多边形内,
则该线段一定在多边形内。证明如下:

命题1:

如果线段和多边形的两相邻交点P1 ,P2的中点P' 也在多边形内,则P1, P2之间的
所有点都在多边形内。

证明:

假设P1,P2之间含有不在多边形内的点,不妨设该点为Q,在P1, P'之间,因为多边
形是闭合曲线,所以其内外部之间有界,而P1属于多边行内部,Q属于多边性外部,
P'属于多边性内部,P1-Q-P'完全连续,所以P1Q和QP'一定跨越多边形的边界,因此
在P1,P'之间至少还有两个该线段和多边形的交点,这和P1P2是相邻两交点矛盾,故
命题成立。证毕

由命题1直接可得出推论:

推论2:

设多边形和线段PQ的交点依次为P1,P2,……Pn,其中Pi和Pi+1是相邻两交点,线段
PQ在多边形内的充要条件是:P,Q在多边形内且对于i =1, 2,……, n-1,Pi ,Pi+1
的中点也在多边形内。

在实际编程中,没有必要计算所有的交点,首先应判断线段和多边形的边是否内交
,倘若线段和多边形的某条边内交则线段一定在多边形外;如果线段和多边形的每
一条边都不内交,则线段和多边形的交点一定是线段的端点或者多边形的顶点,只
要判断点是否在线段上就可以了。

至此我们得出算法如下:


1. if 线端PQ的端点不都在多边形内
2.   then return false;
3. 点集pointSet初始化为空;
4. for 多边形的每条边s
5.   do if 线段的某个端点在s上
6.         then 将该端点加入pointSet;
7.      else if s的某个端点在线段PQ上
8.         then 将该端点加入pointSet;
9.      else if s和线段PQ相交        // 这时候可以肯定是内交
10.        then return false;
11. 将pointSet中的点按照X-Y坐标排序,X坐标小的排在前面,
    对于X坐标相同的点,Y坐标小的排在前面;
12. for pointSet中每两个相邻点 pointSet[i] , pointSet[ i+1]
13.    do if pointSet[i] , pointSet[ i+1] 的中点不在多边形中
14.         then return false;
15. return true;


这个算法的复杂度也是O(n)。其中的排序因为交点数目肯定远小于多边形的顶点数
目n,所以最多是常数级的复杂度,几乎可以忽略不计。


11.判断折线在多边形内


只要判断折线的每条线段是否都在多边形内即可。设折线有m条线段,多边形有n个
顶点,则复杂度为O(m*n)。


12.判断多边形是否在多边形内

只要判断多边形的每条边是否都在多边形内即可。判断一个有m个顶点的多边形是
否在一个有n个顶点的多边形内复杂度为O(m*n)。


13.判断矩形是否在多边形内


将矩形转化为多边形,然后再判断是否在多边形内。


14.判断圆是否在多边形内


只要计算圆心到多边形的每条边的最短距离,如果该距离大于等于圆半径则该圆在
多边形内。计算圆心到多边形每条边最短距离的算法在后文阐述。


15.判断点是否在圆内

计算圆心到该点的距离,如果小于等于半径则该点在圆内。

16.判断线段、折线、矩形、多边形是否在圆内

因为圆是凸集,所以只要判断是否每个顶点都在圆内即可。

17.判断圆是否在圆内

设两圆为O1,O2,半径分别为r1, r2,要判断O2是否在O1内。先比较r1,r2的大小
,如果r1<r2则O2不可能在O1内;否则如果两圆心的距离大于r1 - r2 ,则O2不在
O1内;否则O2在O1内。

18.计算点到线段的最近点

如果该线段平行于X轴(Y轴),则过点point作该线段所在直线的垂线,垂足很容
易求得,然后计算出垂足,如果垂足在线段上则返回垂足,否则返回离垂足近的端
点;

如果该线段不平行于X轴也不平行于Y轴,则斜率存在且不为0。设线段的两端点为
pt1和pt2,斜率为:
k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
该直线方程为:
y = k* ( x - pt1.x) + pt1.y
其垂线的斜率为 - 1 / k,
垂线方程为:
y = (-1/k) * (x - point.x) + point.y
联立两直线方程解得:
x  =  ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1)
y  =  k * ( x - pt1.x) + pt1.y;

然后再判断垂足是否在线段上,如果在线段上则返回垂足;如果不在则计算两端点
到垂足的距离,选择距离垂足较近的端点返回。

19.计算点到折线、矩形、多边形的最近点

只要分别计算点到每条线段的最近点,记录最近距离,取其中最近距离最小的点即
可。

20.计算点到圆的最近距离

如果该点在圆心,则返回UNDEFINED
连接点P和圆心O,如果PO平行于X轴,则根据P在O的左边还是右边计算出最近点的
横坐标为centerPoint.x - radius 或 centerPoint.x + radius, 如图4 (a)所示;
如果PO平行于Y轴,则根据P在O的上边还是下边计算出最近点的纵坐标为
centerPoint.y + radius 或 centerPoint.y - radius, 如图4 (b)所示。

如果PO不平行于X轴和Y轴,则PO的斜率存在且不为0,如图4(c)所示。这时直线PO
斜率为
k = ( P.y - O.y )/  ( P.x - O.x )
直线PO的方程为:
y = k * ( x - P.x) + P.y
设圆方程为:
(x - O.x ) ^2 + ( y - O.y ) ^2 = r ^2,
联立两方程组可以解出直线PO和圆的交点,取其中离P点较近的交点即可。

21.计算两条共线的线段的交点

对于两条共线的线段,它们之间的位置关系有图5所示的几种情况。
图5(a)中两条线段没有交点;图5 (b) 和 (d) 中两条线段有无穷焦点;图5 (c)
中两条线段有一个交点。设line1是两条线段中较长的一条,line2是较短的一条,
如果line1包含了line2的两个端点,则是图5(d)的情况,两线段有无穷交点;如
果line1只包含line2的一个端点,那么如果line1的某个端点等于被line1包含的
line2的那个端点,则是图5(c)的情况,这时两线段只有一个交点,否则就是
图5(c)的情况,两线段也是有无穷的交点;如果line1不包含line2的任何端点,
则是图5(a)的情况,这时两线段没有交点。


22.计算线段或直线与线段的交点

设一条线段为L0 = P1P2,另一条线段或直线为L1 = Q1Q2 ,要计算的就是L0和L1
的交点。

1.首先判断L0和L1是否相交(方法已在前文讨论过),如果不相交则没有交点,
否则说明L0和L1一定有交点,下面就将L0和L1都看作直线来考虑。

2.如果P1和P2横坐标相同,即L0平行于Y轴
  a)若L1也平行于Y轴,
      i.若P1的纵坐标和Q1的纵坐标相同,说明L0和L1共线,假如L1是直线的话他们有
        无穷的交点,假如L1是线段的话可用"计算两条共线线段的交点"的算法求他们
        的交点(该方法在前文已讨论过);
      ii.否则说明L0和L1平行,他们没有交点;
  b)若L1不平行于Y轴,则交点横坐标为P1的横坐标,代入到L1的直线方程中可以计
    算出交点纵坐标;
3.如果P1和P2横坐标不同,但是Q1和Q2横坐标相同,即L1平行于Y轴,则交点横
坐标为Q1的横坐标,代入到L0的直线方程中可以计算出交点纵坐标;
4.如果P1和P2纵坐标相同,即L0平行于X轴
  a)若L1也平行于X轴,
      i.若P1的横坐标和Q1的横坐标相同,说明L0和L1共线,假如L1是直线的话他们
        有无穷的交点,假如L1是线段的话可用"计算两条共线线段的交点"的算法求
        他们的交点(该方法在前文已讨论过);
     ii.否则说明L0和L1平行,他们没有交点;

   b)若L1不平行于X轴,则交点纵坐标为P1的纵坐标,代入到L1的直线方程中可以计
     算出交点横坐标;
5.如果P1和P2纵坐标不同,但是Q1和Q2纵坐标相同,即L1平行于X轴,则交点纵坐标
为Q1的纵坐标,代入到L0的直线方程中可以计算出交点横坐标;
6.剩下的情况就是L1和L0的斜率均存在且不为0的情况
   a)计算出L0的斜率K0,L1的斜率K1 ;
   b)如果K1 = K2
      i.如果Q1在L0上,则说明L0和L1共线,假如L1是直线的话有无穷交点,假如L1
        是线段的话可用"计算两条共线线段的交点"的算法求他们的交点(该方法在
        前文已讨论过);
     ii.如果Q1不在L0上,则说明L0和L1平行,他们没有交点。
   c)联立两直线的方程组可以解出交点来

说明:这个算法并不复杂,但是要分情况讨论清楚,尤其是当两条线段共线的情况
需要单独考虑,所以在前文将求两条共线线段的算法单独写出来。另外,一开始就
先利用矢量叉乘判断线段与线段(或直线)是否相交,如果结果是相交,那么在后
面就可以将线段全部看作直线来考虑。

23.求线段或直线与折线、矩形、多边形的交点

分别求与每条边的交点即可。

24.求线段或直线与圆的交点

设圆心为O,圆半径为r,直线(或线段)L上的两点为P1,P2。
1.如果L是线段且P1,P2都包含在圆O内,则没有交点;否则进行下一步
2.如果L平行于Y轴,
  a)计算圆心到L的距离dis
  b)如果dis > r 则L和圆没有交点;
  c)利用勾股定理,可以求出两交点坐标,如图6(a)所示;但要注意考虑L和圆的相
    切情况
3.如果L平行于X轴,做法与L平行于Y轴的情况类似;
4.如果L既不平行X轴也不平行Y轴,可以求出L的斜率K,然后列出L的点斜式方程
,和圆方程联立即可求解出L和圆的两个交点;
5.如果L是线段,对于2,3,4中求出的交点还要分别判断是否属于该线段的范围内。

 

10:48 | 评论 (5)

2004年8月12日 #

 

  Performance comparison C++, C# and Java

Test System
  • AMD Athlon XP 2200+
  • 1024 MB DDR 266
  • VIA KT266A
  • Windows XP Prof. + SP1

Java Version + Options
  • Java 1.4.2_03
  • Java 1.5 (alpha, 11. Dec. 03)
  • compiler options: -g:none
  • running options: -mx1024m

C# Version + Options
  • .Net Framework 1.1.4322 (Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4)
  • compiler options: /optimize+ /debug- /checked-
  • running options:

C++ Version + Options
  • Microsoft Visual Studio Net 2003 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86)
  • compiler options:  /O2 /Oi /Og /Ot /EHsc /arch:SSE
  • Intel(R) C++ Compiler for 32-bit applications, Version 8.0   Build 20031017Z
  • compiler options:  /fast /G6 /Oi /Og /Ot /EHsc /arch:SSE
  • running options:

Source Code
Original Source Code is from Christopher W. Cowell-Shah http://www.cowell-shah.com/research/benchmark/code and from http://dada.perl.it/shootout/ and Doug Bagley http://www.bagley.org/~doug/shootout . I took portions and whole parts from both and put them into a single file and did some changes + bugfixes.


Results
Maximum memory usage:
  • Java - 163 MB
  • C# - 111 MB
  • Cpp - 98 MB
Performance in ms:

Cpp is the fastest, except the STL "hashmaps" test is a lot slower, maybe someone can take a look at the source code, I use STL <map>, because <hash_map> was slower.... The memory footprint of Cpp is also the lowest, which was expected. C# is quit fast (I would have been surprised, if C# were much slower than Java), but seems to have some problems with exception handling, matrix multiply and nested loops. Java's hash maps are very fast and the exception handling is also very strong. If you sum it up, Java gets 5 wins against C#, C# gets 9 wins against Java and Cpp gets 11 wins against C#. This black and white comparison only takes performance into account, but other values like development speed and security are also very important issues today. In my opinion it goes much faster to develop complex apps with Java or C#, than with plain Cpp and the STL. Type safety and buffer overrun issues are also much weaker in Cpp, so you have to do more work, which takes more time and will cost some speed! So every language has its strong areas, but as always, nothing comes for free...


Update 15.04.04

Java Version + Options
  • Java 1.5 (alpha, 11. Dec. 03)
  • compiler options: -g:none
  • running options: -mx1024m -Xbatch and -server for the server VM
C# Version + Options
  • .Net Framework 1.1.4322 (Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4)
  • compiler options: /optimize+ /debug- /checked-
  • running options:

C++ Version + Options
  • Microsoft Visual Studio Net 2003 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86)
  • compiler options:  /Op /Oy /O2 /Oi /Og /Ot /EHsc /arch:SSE
  • Intel(R) C++ Compiler for 32-bit applications, Version 8.0   Build 20031017Z
  • compiler options:  /Op /Oy /Qpc80 /fast /G6 /Oi /Og /Ot /EHsc /arch:SSE
  • running options:

Source Code Changes
C++ :SLT VECTOR was replaced with the STL LIST, that's why the benchmark is now called "List". STDIO(C) was replaced with FSTREAM(C++).
Java :STRINGBUFFER was replaced with STRINGBUILDER, timeing routines changes, "new Integer()" was replaced with Integer.valueOf(), VECTOR was replaced with LINKEDLIST, so all "List" benchmarks use now a list, only C# uses its ARRAYLIST, because there is no list or linked list in C# and thats the reason, why these benchmark is marked red!

Results
Maximum memory usage:
  • Java - 163 MB
  • C# - 111 MB
  • Cpp - 98 MB
Performance in ms:

Cpp is a little bit slower with more accurate floating point calculations and omitted frame pointers. The Java server VM is faster than the client VM, which was new to me, because I don't have that much Java experience. Trig. functions and maybe the memory footprint are the only weak points in Java today. The "hashmaps" benchmark uses a helper class in Java, to achive this high performance. If you don't use it, you will get 11000ms instead of 3640ms, but this optimisation isn't possible and necessary for the C++ and C# versions!


Update 17.04.04

Java Version + Options
  • Java 1.4.2_03
  • compiler options: -g:none
  • running options: -mx1024m -Xbatch and -server for the server VM
  • Excelsior JET 3.5

Results
Maximum memory usage:
  • Java - 163 MB
  • C# - 111 MB
  • Cpp - 98 MB
Performance in ms:

The server VM (1.4.2_03) is faster than the 1.5(alpha) server VM from above and it's always faster than its client version. The JET 3.5 code is faster than the client VM, but sometimes it is slower than the server VM. Trig. functions are as fast as the Cpp and the C# code, but they seems to use some lower precision for the sin, cos and tan functions.


Feedback
Please use this thread for feedback.
 

9:40 | 评论 (4)

2004年7月21日 #

 

  美国国家安全局在windows中加装间谍密钥


   
近来常看到Hotmail被黑、IE浏览器漏洞百出的报导,微软在计算机安全方面的记录是非常
糟糕。作为用户的我们,大部分人已经对这些小漏洞习以为常。但是我们发现在每一个微软
出售的的Windows拷贝中,都存在着一个给美国国家安全局(NSA-美国的间谍机构)提供的后
门,从而使美国政府可以简单地访问你的计算机,你会怎么想呢?
在研究 Windows NT 4 安全子系统时,Cryptonym公司的首席科学家Andrew Fern发现在Win9
5/98/NT4.0和Windows 2000中存在为美国国家安全局提供的一个后门。该后门表明微软的加
密API(CryptoAPI)结构存在安全漏洞。由于加密API是Windows安全体系的基石,任何的漏洞
都将导致Windows遭受外来的电子攻击。
在CryptoAPI中,我们知道Windows用“加密公钥”在使用CryptoAPI的模块之前来验证这一
模块的一致性。 而在WindowsNT4的补丁5中,微软犯了一个严重的“错误”,忘记将识别安
全部件的符号信息移去。这使得Andrew发现了Windows系统中存在两个密钥,一个属于微软
,用以认证加密API服务,另一属于美国国家安全局,从而也允许它调用加密API服务,从而
无需你的许可访问你的机器。
结果是,美国国家安全局可以轻而易举地无需经过认证调用所有Windows系统的安全服务。
一旦这些服务启动,他们可以完全控制你的机器。对于使用WindowsNT进行安全数据服务的
非美国用户而言,这是十分令人担忧地。美国政府正尽量使在美国之外其它国家很难采用“
强”加密技术。他们在世界最流行的操作系统中安装安全后门将给我们带来强烈震撼。
然而,在这个坏消息中有个好消息。在实现这个“加密认证”功能中也存在一个安全问题。
加密认证启动后,用户可以简单地删除或替换“美国国家安全局”密钥而不破坏操作系统。
由于“美国国家安全局”密钥可以被轻易替换掉,非美国的用户可以方便地在Windows中安
装一个更强的加密服务,而无需经过微软与“美国国家安全局”的同意。一个取代“国家安
全局”密钥的程序可以在HTPP…. 中取得。
技术细节
微软加密API概况
微软加密API(CryptoAPI)允许独立软件开发商(ISV)动态地加载加密模块(CSP): Windows
对加密模块进行签名认证的这一体系结构允许在操作系统中加入不同的加密实现方法。除非
你同意接受美国的出口许可,否则微软不会对你的加密模块提供数字签名。换言之,微软从
不允许非美国的公司在Windows中加入强加密服务。
幸运地是,在这个图中的“加密服务提供者”的数字签名程序有一个安全问题。漏洞是怎么
发现的 使用NT4服务器,补丁5(美国版,128位加密版),Visual C++ 6,补丁3。同样的结
果可以在Win95osr2, Win98, Win98黄金版,WinNT4(所有版本),与Windows2000(到预发布版
1为止)  

通过调试器可以看到:

在加密服务提供者装载前 在动态连接库 ADVAPI32.DLL 中
地址 0x77DF5530 A9 F1 CB 3F DB 97 F5 ... ... ...
地址 0x77DF55D0 90 C6 5F 68 6B 9B D4 ... ... ...

在RC4加密方法使用后 可以看到
A2 17 9C 98 CA R S A 1 ... 00 01 00 01 ...(看起来像RSA密钥)
A0 15 9E 9A CB R S A 1 ... 00 01 00 01 ...(看起来像RSA密钥)

检查SP5的补丁中的符号表 在"_CProvVerifyImage@8" 中
地址 0x77DF5530 标记为“_KEY”
地址 0x77DF55D0 标记为 “_NSAKEY”

为什么人们认为这是一个“间谍密钥”呢?

1. 这个密钥令人吃惊地叫候选作“NSA密钥”, 即为美国国家安全局National
Security Agency 的缩写“NSA”;
2. 在Windows中存在这第二个密钥是从不为人知的;
3. 这第二个密钥是用来干什么的呢?
4. 根据微软的说法,这是一个“备用”的密钥,该密钥是应美国国家安全局要求设立的。
 
 

13:37 | 评论 (2)

2004年7月16日 #

 

  很久没有来过了,全都变了!

请问管理员还能继续提供AnotherEon002这种风格吗?
 

19:37 | 评论 (5)

 

  关于租赁的生存期

DCOM中使用引用计数来判断是否有客户端仍在使用某个对象.当引用计数变为0时,DCOM就知道可以安全地销毁这个对象了.这种解决方案的弱点是每个客户端必须显示通知服务器端已经用完这个对象.如果某个客户端没有这样做,那么这个对象就可能会一直存在.

有两种情况可能导致这种方法失败.

  1. 网络连接丢失或者客户端进程在释放远程对象之前崩溃.可以通过周期性ping远程客户来保证客户端是否活动.但是会消耗局域网上的网络带宽,这对INTERNET连接来说就更加昂贵了.
  2. 贪婪客户端.可能是偶然也可能是被设计成这样,这种客户端会永远保持对某个远程对象的引用,即使这个对象很少或根本没有被用到.对无状态服务器影响不大.

    .NET的租赁分布式垃圾收集器可以解决这两种情况.无论何时在服务器端建立一个客户端活动对象或一个已知的Singleton对象,运行库都会为这个对象分配一个固定的生存期,称作租赁.当租赁期到时,运行库会释放对这个对象的引用,然后将它交递给下一个垃圾收集器.然而,只要客户端调用了这个对象的一个方法,运行库都会更新这个对象的租赁.这种简单的解决方案可以保证有状态对象的存活并在一段合理的时间内处于激活状态.由于对象可以在空闲一段时间后被自动释放,这样就不需要求助于使用无状态对象来解决这样贪婪客户端问题.而且服务器端不需要再PING每个客户端以确认它们是否在活动.

 

11:15 | 评论 (0)

 

  关于IP数组的建立

在本系统中将通过多个客户端对一个IP数组的同步访问实现并行计算.

一个IP地址到十进制转换如下

192.168.0.1=(192<<24)+(168<<16)+(0<<8)+1=3232235521

 

但是IPAddress中的Address是网络字节序,也就是说在内存中存放的时候,4个部分是反序存放的,因此

 IPAddress ipAddr=IPAddress.Parse("192.168.0.1");

后得到的ipAddr.Address=16820416

  实际上就是16820416=(1<<24)+(0<<16)+(168<<8)+(192<<1);

 

所以当你的ipAddr.Address++后,实际上=(1<<24)+(0<<16)+(168<<8)+(193<<1),就是193.168.0.1

 

要实现IP地址的循环用IPAddress比较麻烦;你可以将点分十进制的4个部分构造成一个4重循环,但是效率低点。

 

我们也可以直接构造循环,利用前面的转换规则。

 

本程序实现函数

//将基于字符串的IP转换成主机字节序的IP地址

private static int ParseIPAddress(string strIPAddress)

        {

            try

            {

                IPAddress ipAddr=IPAddress.Parse(strIPAddress);

                byte[] ipBytes=ipAddr.GetAddressBytes();

                return (ipBytes[0]<<24)+(ipBytes[1]<<16)+(ipBytes[2]<<8)+(ipBytes[3]);

            }

            catch

            {

                return 0;

            }

        }

//转换后建立数组

               int nStartIP = ParseIPAddress(tStartIp.Text.Trim());

            int nEndIP = ParseIPAddress(tEndIp.Text.Trim());

            Digits = nEndIP - nStartIP;

            IPlist = new IPAddress[n];

            int j=0;

 

            for(int i=nStartIP;i<nEndIP;nStartIP++,j++)

            {

                IPlist[j] = new IPAddress(System.Net.IPAddress.HostToNetworkOrder(i));

            }

 

11:14 | 评论 (0)

2004年5月18日 #

 

  模糊:让你的代码远离偷窥之眼【转载】

我们知道,Java编译源程序得到的是字节码,VS.NET编译源程序得到的是MSIL(Microsoft中间语言),这种编译方式称为“不完全编译”,特别容易被反编译或实施反向工程。与本机代码不同,不完全编译得到的中间代码完整地保留了变量、过程名称,从而使反编译得到的程序几乎与原始程序完全一样,只缺少原始程序的注释,其余内容差不多可以原封不动地还原出来。

  对于商品软件的开发者,高质量的反编译代码带来了很大的风险:算法可能被窃取和改造,程序代码可能被复制和更改。(即使单位内部使用的非商品软件,由于反编译造成的源代码泄漏也带来很大的威胁。例如,用户将很容易看到访问数据库的密码或程序嵌入的SQL命令。同样地,使用外单位托管服务器的网站也面临风险,一旦上载了ASP.NET应用的代码,托管单位的人就可能随意查看和更改程序代码)。

  更让人担心的是,现在黑客或好奇的用户能够方便地得到各种反向工程工具。Microsoft本身就免费提供了一个MSIL反汇编器,称为ILDASM;这里有一个源代码开放的.NET反编译工具Anakrino;当然,还有其他许多厂商提供了商品化的反向工程工具。

  一、修改变量名称

  为防止这类反向工程的威胁,最有效的办法是模糊。(据《美国传统辞典》,“模糊”的意思是“使混乱,使糊涂迷惑,使过于混乱或模糊,使得难于感觉或理解”)。模糊工具运用各种手段达到这一目标,但主要的途径是让变量名字不再具有指示其作用的能力、加密字符串和文字、插入各种欺骗指令使反编译得到的代码不可再编译。

  一个即将发布的Visual Studio版本(称为VS.NET 2003,代码名称Everett)将集成一个模糊工具,Microsoft建议用这个工具对.NET中间代码进行最后的处理。这个模糊器是另一个工具Dotfuscator的所谓Lite版。由Preemptive Solutions公司出品的Dotfuscator功能更强大,这家位于美国俄亥俄州东北部克利夫兰的公司最初开发Java代码的模糊技术。Dotfuscator模糊器利用一系列卓越的技术使反向工程徒劳无功,或者至少说使得反向工程很难进行。

  Preemptive Solutions公司给它修改中间代码中变量名称的专利技术取了一个叫“超载感应”(Overload induction)的名称,VS.NET 2003带来的Lite版只有这种模糊功能。(模糊器永远不会改动原始的源代码,甚至根本不需要用源代码作为参考。)这种技术充分运用了VS.NET代码的特点:同一个标识符可同时运用于具有不同特征的类和方法;在不同的名称空间中,变量可以有相同的名字而不会冲突。

  Dotfuscator充分运用VS.NET这些符号学上的特点,把尽可能多的符号改成字母“A”。据该公司说,某些代码大约有33%的引用可以改成“A”,还有10%可以改成“B”。经过模糊器这一处理,反向工程得到的代码将很难理解。下面来看一个例子。

  对未经模糊处理的代码执行反向工程:

private void CalcPayroll(SpecialList employeeGroup) {
   while (employeeGroup.HasMore()) {
       employee = employeeGroup.GetNext(true);
       employee.updateSalary();
       DistributeCheck(employee);
    }
}


  同样的代码,经过模糊处理再执行反向工程:

private void a(a b) {
    while (b.a()) {
        a = b.a(true);
        a.a();
        a(a);
    }
}


  显然,两段代码的处理逻辑相同。但是,要说清楚第二段代码到底在做些什么极其困难,甚至要判断它正在访问哪些方法、哪些变量也很困难。

  这种改变变量名称的功能是可配置的,例如,假设你正在构造一个DLL,可以要求不改动API。有趣的是,这一处理过程显然只是简单地把大量变量的名称简缩成单个字符,但获得了非常好的模糊效果。

  二、加密字符串

  字符串加密对付另一个安全问题,其实这一安全问题在本机代码中也同样存在——从二进制代码提取字符和文字是一件很简单的事情。例如,用UNIX的strings工具处理任何二进制文件,可以迅速得到该二进制文件包含的ASCII文本清单。

  在最简单的情形下,这个清单只会泄露版权信息和二进制执行文件引用了哪些库。但是,如果程序要访问数据库,这个清单将包含所有的SQL命令;如果代码模块中嵌入了密码,密码也将不密。

  对于中间代码,未加密的字符串还会带来一层额外的风险。黑客们通过分析对特定字符串的引用,可以判断出从哪里开始代码受到密码保护,然后加上补丁使代码绕过密码验证部分。

  为了解决字符串明文带来的安全问题,大多数模糊器运用了加密字符串的技术。由于解密操作需要一定的开销,所以运行时访问字符串的性能肯定会有所降低。有趣的是,在这方面本机代码反而不占便宜,因为如果要达到同样的效果,对于本机代码开发者必须手工加密和解密每个字符串,而对于中间代码这些工作却可以由模糊器代劳。

  三、隐藏执行流程

  控制流程模糊是一种用来误导反编译器的技术,它在原始的代码中插入许多goto指令,虽然程序最终执行的指令序列仍跟原来的一样,但太多的“迂回动作”使得分析程序实际的逻辑流程非常困难。下面来看一个例子。

  对没有经过控制流程模糊处理的中间代码实施反向工程:

public int CompareTo(Object o) {
  int n = occurrences - ((WordOccurrence)o).occurrences;
  if (n == 0) {
    n = String.Compare(word, ((WordOccurrence)o).word;
  }
  return (n);
}


  同样的代码,经过控制流程模糊处理后再执行反向工程:

public virtual int a(object A_0) {
  int local0;
  int local1;

  local0 = this.a - (c) A_0.a;
  if (local0 != 0)
          goto i0;
      goto i1;
      while (true) {
          return local1;
          i0: local1 = local0;
      }
      i1: local0 = System.String.Compare(this.b, (c) A_0.b);
      goto i0;
}


  可以看到,经过控制流程模糊处理后,代码被插入了一个伪条件检测语句,接着又执行了一个goto指令。在goto的目的地,原来的语句(以经过模糊处理后的形式)被执行,接着又是一个goto语句将控制转到原先的逻辑流程分支。注意while()循环未被执行,它只是起到一种误导的作用。这个代码片断很小,即使没有原始的代码可供比较和参考,识别出程序实际流程的可能性仍存在。然而,对于一个规模较大的过程,如果没有源代码可供参考,那些专门用来搅浑程序正常执行流程的指令将使分析代码的人疲于奔命,最终不得不放弃。

  也就是说,这种模糊处理的根本思想是让恢复原始代码变得极其困难,迫使黑客改变主意,也许是换做轻松一点的,例如“自己写代码算了”。

  对控制流程进行模糊处理要在二进制文件中插入一些代码,因而增加了一些运行时间开销。如果代码对运行时间的要求非常苛刻,可以只给那些特别重要的部分加上这一层额外的保护。

  █ 模糊器和反编译器大展播:

  ▲模糊器:

  LSW DotNet IL Obfuscator

  Demeanor for .NET

  Salamander .NET Obfuscator

  dotfuscator

  Aspose.Obfuscator

  .NET IL-Obfuscator

  Deploy .NET

  Salamander .NET Protector

  Thinstall

  XenoCode

  ▲ 反编译器:

  Salamander .NET Decompiler

  Exemplar/Anakrino
 

1:18 | 评论 (3)

2004年5月16日 #

 

  “震荡波”病毒破坏方式

在本地开辟后门。监听TCP 5554端口,做为FTP服务器等待远程控制命令。病毒以FTP的形式提供文件传送。黑客可以通过这个端口偷窃用户机器的文件和其他信息。 病毒开辟128个扫描线程。以本地IP地址为基础,取随机IP地址,疯狂的试探连接445端口,试图利用windows的LSASS 中存在一个缓冲区溢出漏洞进行攻击,一旦攻击成功会导致对方机器感染此病毒并进行下一轮的传播,攻击失败也会造成对方机器的缓冲区溢出,导致对方机器程序非法操作,以及系统异常等。 打算在用c#试试,呵呵
 

3:30 | 评论 (1)

2004年4月29日 #

 

  一点小建议!

我们的BLOG能提供文件上传的功能吗?: p
 

1:06 | 评论 (9)

2004年4月28日 #

 

  C#的四个基本技巧

C#的四个基本技巧
--

  1.如果可能尽量使用接口来编程 
  
  .NET框架包括类和接口,在编写程序的时候,你可能知道正在用.NET的哪个类。然而,在这种情况下如果你用.NET支持的接口而不是它的类来编程时,代码会变得更加稳定、可用性会更高。请分析下面的代码: 
     
  private void LoadList (object [] items, ListBox l)
  {
   for (int i = 0; i < items.Length;i++)
    l.Items.Add (items[i].ToString ());
  } 
  
  这个函数从一个可为任何对象的数组中加载ListBox,这段代码被限定为只能使用数组。假想过些时候你发现那些对象存在数据库中,或别的集合中。那么你需要修改程序来使用不同的集合类型。如果你用ICollection接口来写那段程序,你就不用修改那段程序了,对于任何实现ICollection接口的类型它都能很好的工作:
  
  private void LoadList (ICollection items,ListBox l)
  {
    foreach (object o in items)
    l.Items.Add (o.ToString ());
  } 
  
  ICollection被数组和所有System.Collection中的集合实现。此外,多维数组也支持ICollection接口。如果那还不够的话,数据库.NET类同样支持ICollection接口。用接口写的这个函数不用需改就可以才许多中情况下使用。 
  
  2. 使用属性代替原始数据 
  
  因为属性已经成为语言本身的元素,所以声明数据元素时它的作用域等级没有必要大于private。因为代码本身会把属性看成数据元素,你并没有失去使用简单数据类型的便利性 。相反它会使你的代码更加灵活功能更加强大。属性使你的数据元素封装性更好。属性可以让你使用lazy evaluation来返回数据。lazy evaluation的意思是当用户请求时才计算它的值,而不是一直保留着它。

  最后,属性可以是virtual也可以是abstract。你也可以在接口中定义属性。 
  
  这里还有维护方面的因素应当注意:尽管操作两者的方法是一样的,但是你把一个数据元素变成属性,那么原先客户端的程序便不能访问服务端的新版本程序了。实际上对于在Web service中你想实现序列化的值你可以把它们变成属性来使用:
  
  private int TheMonth = 0;
  
  [XmlAttribute ("Month")]
  public int Month
  {
   get {
    return TheMonth;
   }
   set {
    TheMonth = value;
   }
  } 
  
  简单通过属性就可以使你的所有数据元素私有化。 
  
  3. 在Producer/Consumer 的Idiom中使用Delegate 
  
  当你生成一个实现producer idiom类的时候,使用deletate来通知consumer。这种方法相对于用接口更加灵活。Delegate是多点传送的,所以不用加额外的代码你就何以支持多用户。相对于用接口这样做可使类之间的耦合性降低。 
  
  下面的类处理键盘输入并把它传给所有的registered listeners:
  
  public class KeyboardProcessor
  {
  private OnGetLine theFunc = null;
  
  public OnGetLine OnGetLineCallback {
   get {
    return theFunc;
   }
   set {
    theFunc = value;
   }
  }
  
  public void Run (){
  // Read input.
  // If there is any listeners, publish:
  string s;
  do {
   s = Console.ReadLine ();
   if (s.Length == 0)
    break;
   if (theFunc != null){
    System.Delegate [] funcs =theFunc.GetInvocationList();
    foreach (OnGetLine f in funcs) {
     try {
      f (s);
     } catch (Exception e) {
      Console.WriteLine
      ("Caught Exception: {0}", e.Message);
     }
    }
   }
  } while (true);
  } 
  
  任何数目的listeners都可注册到producer,它们所要做的只是提供一个特定的函数:deletate。 
  
  4. 注意初始化顺序 
  
  C#中对于一些变量声明加入了initializer的概念。它们在构造函数之前被执行,实际上变量在基类的构造函数执行前之前被初始化。 
  
  所以,在初始化变量的时候不要用基类中的数据,因为它们还没有被构造。

 

6:01 | 评论 (4)

2004年4月27日 #

 

  PanelBar control for ASP.NET

 

Sample Image - PanelBar.jpg

Introduction

The PanelBar control is a rich UI web control. It can be used to build an Outlook-style application. I'm providing this control as a sample for building ASP.NET custom controls. Click here for an online demo.

Using the control

The PanelBar has full design support. So, using the control is fairly simple. Just install the component by adding the PanelBar.dll to the list of components in Visual Studio. NET. Drag an instance of the PanelBar component on a form and set the design-time properties. The PanelBar has an items property which gives access to the collection of PanelBarItems. The appearance of each button can be set by using the Text and ImageUrl properties. The PanelBar component also has an ImageUrl property that is used for providing a default image for the buttons.

About the code

The code is very well commented. The following classes are defined:

  • ScrollPanel: implements a scrollable Panel, used as a base class for the PanelBar control
  • PanelBar: implements the PanelBar control
  • PanelBarItem: implements the PanelBar buttons (consists of a LinkButton and an ImageButton)
  • PanelBarControlBuilder: implements the control builder for the PanelBar
  • PanelBarControlDesigner: implements the control designer for the PanelBar

    原文地址:http://www.codeproject.com/aspnet/panelbar.asp
 

6:14 | 评论 (3)

2