如果回到1997。

2008-10-26 发表在 记录思考 | 查看 104 次 | 3 条评论

http://www.tianya.cn/publicforum/content/funinfo/1/1169698.shtml

这是天涯上很火的帖子。在枣报上看到的。
很多的回复让人触动。我忽而觉得,这世上很多的美好和感动,都是小角色创造的。

如果自己回到1997,我却记不起最想做什么了。

日子就像长途巴士。

2008-10-25 发表在 记录思考 | 查看 101 次 | 2 条评论

我从家乐福的班车上跳下来的时候,看到路边的地摊只剩下从我搬到这里就在一直坚持着的炒饭,前一阵子出现的麻辣烫和小炒已经连续几天不见了。再看着不知什么缘故被挖得泥泞不堪的马路,和阴湿的天气,我忽而觉得,这日子,就像做着一辆长途巴士,从早到晚,从黑夜到白天,风景一直变化着,你不知疲倦却又有点不耐烦,终究不知道何时才是终点。

大学里每次从家到东北,都是坐长途巴士到烟台再改坐轮船。这段坐长途大巴的经历,却是至今难忘。黄昏的时候,插上耳机,听许巍的歌。在晃动的车厢里看窗外摇曳陌生的风景,夕阳透过灰蒙蒙的玻璃折射进来,卧铺上被翻洗过多次却仍然有着混合了多种人的气息的余味,在这时仿佛都成为宁静的一种。安详。不知道终点在那里,旅途也并不精彩,但是我能感觉,有了这些,我就可以忍受着等待。

昨天下班接到爸妈的电话,妈妈哽咽着说外公在昨天下午走了。问我能不能抽空回去。妈妈说,要是公司忙就别回来了,回来的话可能要好多天,而且毕竟是外孙。我首先想当然是应该回去。外公外婆生前对我怎样,我其时记得不清楚,只知他们对我不薄。但是我突然想到上次回去时,外公握着我的手说想我,我便顿觉物是人非。至从外公患了癌症,大家都知道外公余日不多。可是真正到了那天,大家还是悲痛得无法收拾。我尚且不知道回去该怎么面对,不知该怎样在众人面前表示我的悲痛。我后来想,几个早逝的亲戚,他们的儿子在接待的时候,也并未表现得悲痛欲绝。妈妈过一阵子打来电话说,你就不用回来了,只要记得外公就好。

我在QQ上对Tammy说,最近很不喜欢一个人,总想有个人陪着。我知道,这是前一阵子腰扭伤的缘故。那天早上,趴着睡了一晚之后,我的脖子已经让我痛不欲生。可是没想到后来的疼痛却更让我几近崩溃。我强忍着疼痛从趴着变成躺着,然后坐在床边,却发现再也不能站起来和弯腰了。我试了半小时,都宣告失败。我想打电话让爸妈过来照顾我,我想打电话给120让他们抬着病床过来接我住院,我好希望这时的我不是单身,身边有个女朋友照顾我。可是……我知道这些都无法实现,就算能实现,我也需要能行走。我只好将手边的布料塞进嘴里,忍着疼痛,从床边站了起来,并声嘶力竭地去弯腰、直立、再弯腰……我坐在床边是早上6点,到我能站起来已经是8点半。还好有老虎帮忙,不然我真不知道该怎么办。我想起爸爸常叮咛我的话,出门靠朋友。

公司这一阵子忙的项目快收尾了。最近部门内有些燥乱,缺少激情,大家都觉有力无处可使。于是也开始抱怨起来了。这大概是年轻的部门发展中必经的阶段吧。我还是充满乐观的。入手相机一部,平民级,不过够我用的了。

字符串、字符数组、数组、指针关系总结。

2008-10-25 发表在 程序开发 | 查看 56 次 | 评论
【规则】
1string为普通类型,不是数组型,只是其内容为字符串;
2’a’”a”的区别:’a’为字符,”a”为字符串;单引号只能定义一个字符,双引号可以定义多个字符,即字符串。
3、指针可以通过加减、自加减改变其值,数组不可以。
4、以数组定义的字符串可以修改其中的字符,以指针定义的字符串不能修改其中的字符。
 
例如:
char a[]=”hello”;
cout<<a;               //输出 hello
cout<<*(a+1);      //输出 e,即数组a的第2个字符,即a[1]
cout<<a[1];          //输出 e,即数组a的第2个字符,与上同
cout<<*a++;        //错误,规则3,数组名是常量,不可以改变其值
cout<<*a;            //输出 h,即数组a的第一个字符
cout<<a;              //输出hello
*a=”L”;            //错误,规则2,*a为字符,”L”为字符串,不匹配
*a=’L’;            //正确,规则4,将数组第一个字符修改为L
cout<<a;              //输出 Lello
a[2]=’6’;          //正确,规则4,将数组第3个字符修改为’6’
cout<<a;              //输出 Le6lo
 
char *a="hello";
cout<<a;            //输出 hello
cout<<*(a+1);    //输出 e,即字符串a的第2个字符
cout<<a[1];        //输出 e,即字符串a的第2个字符,这里也可以视为数组a
cout<<*a++;      //输出 h,,规则3,即先计算*a,再使a=a+1
cout<<*a;          //输出 e,因上一行中a已经自加1
cout<<a;            //输出 ello,因为指针a已经发生变化,指向了下一个地址,即指向以e开头的字符串
*a=’L’;         //错误,规则4,不能修改指针定义的字符串的字符。
                           //【注意】此处编译可通过,运行时会出错,提示“不能写入”
a[2]=’6’;      //错误,规则4,不能修改指针定义的字符串的字符。
 

 

string型(需要string头文件)
char型(不需要string头文件)
 
 
char a=’m’;
正确
 
 
char a=”m”;
错误
 
 
char *a=”m”;
正确
 
 
char a[]=”m”;
正确
string a=”hello”;
正确
char a=”hello”;
错误
string *a=”hello”;
错误
char *a=”hello”;
正确
string a[]=”hello”;
错误
char a[]=”hello”;
正确
string *p=a;
错误
char *p=a;
正确
string *p=&a;
正确
char *p=&a;
错误
cout<<a;
a的值
cout<<a;
a的值
cout<<*a;
错误
cout<<*a;
a的首字符
cout<<&a;
a的地址
cout<<&a;
a的地址
 

1、 字符数组相当于字符串

2、其末尾字符为’ \0 ‘

3、其长度=有效字符数+1,在定义字符数组长度时切记。

4、初始化方法
① char arr[6] = {"hello"};
② char arr[6] = "hello"; //与第①种相同,一般使用这一个
③ char arr[6] = {‘h’,'e’,'l’,'l’,'o’,'\0′}; //主要在特殊字符时使用

5、"a" 和 ‘a’ 的区别:前者是字符串,占用2个字节空间,后者是字符,占用1个字节空间。

6、数组长度计算:
(1)sizeof
方法:sizeof(数组名)/ sizeof(数组类型名)
说明:数组占用字节除以数组类型所占字节,结果为数组元素个数
(2)strlen
说明:strlen,求字符串有效长度
方法:strlen(字符数组名) //结果为字符数组有效字符长度,不包括末尾的’ \0′

对于char arr[]="hello";来说,sizeof(arr)为6,包含了数组末尾的’\0′,而strlen(arr)为5,不包含末尾的’\0′;
而对于其它类型的数组来说,没有strlen命令,sizeof(数组名)计算的结果就是这个数组所占用的字节数。

7、字符数组输出的特殊性

C++规定,数组的名称就是数组的首地址,对于a[ ]来说,a就是数组a的地址,但是在输出字符数组时,却有特殊的地方:

 

#include<iostream>
using namespace std;
void main()
{
  char a[]="How a you!";
  cout<<"a="<<a<<endl;
  char c[]={‘H’,'o’,'w’,’ ‘,’a',’ ‘,’y',’o',’u',’!',’\0′};
  cout<<"c="<<c<<endl;

  int b[]={1,2,3,4,5,6,7,8,9};
  cout<<"b="<<b<<endl;
}

对常规数组来说,输出要使用循环。但是在上例中,输出字符数组(字符串)时,使用cout可以直接输出。

运行结果:

a=How a you!
c=How a you!
b=0012FF44

由此可见:

不管是用双引号还是单引号初始化的字符数组,用cout<<字符数组名 的格式,都可以直接输出该数组。而不是输出数组的首地址;
要输出字符数组的首地址,必须使用cout<<&数组名 的格式。

而输出整型数组及其它数组时,使用cout<<数组名 ,输出的只能是数组的首地址。
要输出整个数组,必须使用循环。

切勿让“黑屏”“黑”了你的电脑。

2008-10-20 发表在 工作那点事 | 查看 31 次 | 评论

http://blog.sina.com.cn/s/blog_59acc8e20100azmk.html

谁动了我的网页后续之——ARP挂马

2008-10-11 发表在 工作那点事 | 查看 31 次 | 评论

本文介绍的将是一种“奇特”的挂马方式:ARP挂马。
与前文介绍的服务器端网站挂马方式不同的是,ARP挂马并不是针对网站服务器端,也就是说,ARP挂马并没有入侵网站服务器,对网站的网页文件做出实质上的修改。这时也许你就会想,肯定是客户端那里中病毒了。不一定!ARP挂马的奇怪之处就在于:网站本身没有被修改,正在浏览该网站的客户机也没有感染病毒,但是用户正在浏览的网页却是被挂马的。

这就是ARP病毒在作祟。
让我们先来简单普及一下ARP的概念。
ISO将整个计算机网络通信功能划分为7个层次:
第七层  应用层
第六层  表示层
第五层  会话层
第四层  传输层
第三层  网络层
第二层  数据链路层
第一层  物理层

地址解析协议(Address Resolution Protocol,ARP)具体说来就是将网络层(IP层)地址解析为数据链路层(MAC层)的MAC地址。为什么要这样转换呢?因为局域网的网络流通不是根据IP地址进行,而是按照MAC地址进行传输。

比如vlan中有两台机器A(192.168.1.2)、B(192.168.1.3)。
计算机A是如何得知B的MAC地址的呢?就是通过ARP协议。
在A不知道B的MAC地址的情况下,A就广播一个ARP请求包,请求包中填有B的IP(192.168.1.2),vlan的所有计算机都会接收这个请求,而正常的情况下只有B会给出ARP应答包,包中就填充上了B的MAC地址,并回复给A。
A得到ARP应答后,将B的MAC地址放入本机缓存。但是MAC缓存是有生存周期的,生存周期到了之后后,就又会发广播包,即重复上面的过程。——因此可以预想,ARP病毒肯定是一直循环发送广播包,用来更新客户机的ARP缓存表的。

这属于Ask-Answer模式,当然,ARP协议并不只在发送了ARP请求才接收ARP应答。只要计算机接收到ARP应答数据包,就会对本地的ARP缓存进行更新,将应答中的IP和 MAC地址存储在ARP缓存中。注意,ARP病毒正是利用了这种原理,当局域网中的某台机器B向A发送一个自己伪造的ARP应答,而如果这个应答是B冒充C伪造来的,即IP地址为C的 IP,而MAC地址是伪造的,则当A接收到B伪造的ARP应答后,就会更新本地的ARP缓存,这样在A看来C的IP地址没有变,而它的MAC地址已经不是原来那个了。如果这个MAC是不存在的,就会造成网络不通,导致A不能Ping通C!这就是一个简单的ARP欺骗。

所以,大家可以设想,如果B发送的欺骗包 是用来修改客户机的ARP缓存吧里的“网关的MAC地址”的,那会带来什么后果。
我们假设B中了ARP病毒,因此向局域网内所有机器发送广播包,告诉这些机器,网关的MAC地址是B的MAC,那么vlan里所有机器在访问Internet时:
(1)http请求的数据包首先都会到达B那里,B的病毒逻辑模块会判断是哪个客户端发过来的包,转然后再转给原先的网关,与Internet通信;
(2)原先的网关给B返回HTTP响应的时候,B的病毒逻辑模块在HTTP响应包中,插入一段挂马的代码,比如