创意验证码
行走网上,不免看到好的服务,想要使用,于是第一道门槛就是注册,而且现在为了防止机器自动注册,大多采用了验证码,就此一验证码,各家是各有特色啊,一般的纯字母数字组合的不再提,而Yahoo,Google的要是碰上了的话,是个人都半天认不出来,更不要说机器了,传说这才是真正功能强大的验证码,但是人都认不出来怎么办,来个声音提示,读一遍就行了。
记得以前看到过一个新奇验证码的集合,不过不记得地方了,也没有收集下来,大概记得有个叫计算极限的比较有意思,类似这种
请输入下列式子的答案:
这样的我觉得创意已经够好了,结果今天看到一个更绝的:
这个应该还好吧,不过我刷新了一下,看这个
上面那个还可以用眼睛看出来,这个就得好好花一点功夫了,非geek不会玩这种东东。
一般都会跑一下这个程序来得到结果,这里有在线服务可以办到这事,强强的codepad就可以。
Linux死机了怎么办
使用电脑死机是很正常的事,如果系统负载过大,那么程序不能及时响应,很容易死机的。对于个人用户来说,没什么大 不了的,我强行关机再重启就解决问题了,但是如果是在服务器上呢,且不说服务器需要全天候工作提供服务,不能停止,更重要的是数据的安全,强行关机的话未同步的数据就会丢失,这是不允许出现的情况,那要怎么办呢?
如果是在图形界面下死机的话,不要再依赖任何图形界面的工具,那样只会适得其反,可以先试试文字界面,按ctrl+alt+f2(F1-F6一般都可以),会切换到另外一个虚拟终端,需要一个账号来登入,这时键盘响应可能非常慢,但是是可以响应的,进入后打top命令看一下进程,等这个表刷那么一两次,就可以确定占用资源比较大的进程了,把它kill掉,这样可以解决相当一部分问题。
但是有的时候是比较底层的软件出现问题,那这个方法就不适用了,但是这就引出了这篇文章要说的强强的方法。reisub方法,说具体一点,是一种系统请求,直接交给内核处理。键盘上一般都有一个键,SysRq,和PrintScreen在一个键位上,这就是系统请求的键。这个方法可以在死机的情况下安全的重启计算机,数据不会丢失。
具体操作是,按住Alt+SysRq,再依次按下reisub几个键,按完b系统就会重启。
下面解释一下这个方法:其实 Sys Rq 是一种叫做系统请求的东西,按住 Alt-Print 的时候就相当于按住了 Sys Rq 键,这个时候输入的一切都会直接由 Linux 内核来处理,它可以进行许多低级操作。这个时候 reisub 中的每一个字母都是一个独立操作,他们分别表示:
unRaw 将键盘控制从 X Server 那里抢回来
tErminate 给所有进程发送 SIGTERM 信号,让他们自己解决善后
kIll 给所有进程发送 SIGKILL 信号,强制他们马上关闭
Sync 将所有数据同步至磁盘
Unmount 将所有分区挂载为只读模式
reBoot 重启
这里有个问题要注意一下,最好不要快速连续地按下这几个键,要有间隔,大概是估计每个间隔10秒左右,因为每一步操作都需要时间,而且s键之后因为同步数据比较慢,可以停20秒。
最后一个问题是怎么记住这个方法呢,当然记住了上面说的每一步操作的也可以记住,但是这里有个比较好一点的方法,那就是reisub正好是busier反着写的顺序,而busier这么好记,正好还有系统很繁忙的意思,不错。
这样的话在对付linux死机的时候又多了一个杀手锏。
更多关于sys request的内容请稳步这里。
消失的11天
最近做一个万年历的作业,粗粗了解了下历法,做农历的时候发现农历没有固定的算法,只能查表来计算,中华人民共和国提供了1800-2100三百年间的标准农历供使用,于是一下子限制了我的程序的查询范围。所以想着公历的准确,计算的容易,可是正想着公历算法的好呢,发现了一个问题,那就是以前公历不大完善的时候,也有问题。
比如这个,在linux下打入这个命令(windows限制时间范围是1980-2099,所以看不到这个现象)
crane@debian:~$ cal 9 1752
September 1752
Su Mo Tu We Th Fr Sa
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
cal 9 1752就是查询1752年9月的日历,于是很跌眼镜的发现,2号后面就是14号,少了11天,怎么回事呢?
查了下资料,发现是因为历法调整的问题。
1582年2月,罗马教廷要求从1582 年10月中减去10天,因此1852 年10月4日后面紧跟着就是15日。在意大利、西班牙等国家都这样处理了。其他天主教国家也很快跟着这么做了,但是新教国家不愿意修改,而且希腊等东正教 国家直到20世纪初才修改,所以这个改革在英国及其殖民地(包括美国)在1752年9月才被执行。这样 1752 年9月2日后面跟着的就是1752 年9月14日。 这就是为什么cal会生成上面输出的原因了。
这里有个问题,上面说教廷说的是减去10天,但是刚才发现1752年9月减了11天,这是为什么呢?
这是历法转换的问题,现行公历叫格里历(Gregorian calendar),这是十六世纪的罗马教皇Gregorian XIII (格里十三世)针对当时使用的儒略历 (Julian calendar)进行修订后,于1582年10月开始实行的。所以就出现了上面的1582年10月调整10天的情况。但是由于写cal的是美国人,cal是从AT&T的Unix中出来的,前面说到过,美国跟从英国的历法是从1752年才开始改的,所以不太一样,所以还牵涉了1600-1800年的一些问题。
根本原因是因为1800年以前的闰年计算的问题,我们知道闰年是4年一闰,百年不闰,400年再闰,但是1800年以前(所以不包括1800年)没百年不闰,所以就出现了偏差,比如我们可以看一下
crane@debian:~$ cal 2 1700
February 1700
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29
crane@debian:~$ cal 2 1600
February 1600
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29
可以清楚地看到,1600和1700年2月都是29天,一眼看去,想当然的认为多算了17天,其实实际上多算了13天,因为400,800,1200,1600是闰年,2月应该有29天。但是为什么调整的时候只少了11天呢,有个很纠结的原因,由于儒略历 (Julian calendar)公元前闰年的不规则,少算了2个闰年,从13天中去掉2天,所以在cal中看到的是少了11天。
话说回来,做万年历的时候这可是陷阱啊,得小心才是。
超级快速关机方法
最近不知什么问题,发现有时关机时停在windows正在关机那里时间比较长,而且是偶尔快偶尔慢,吃不准是什么原因,于是就想着有什么好的快速关机的方法。
首先想到的就是那个经典的操作技巧,打开任务管理器,在关机菜单中按住ctrl的同时点关闭,片刻间,机子就关了。
算算这个所费的时间,打开任务管理器(不管是任务栏右键打开还是快捷键),再选菜单,点关闭,得10秒左右吧!
程序员的话就会多想一点,这个玩意用程序怎么实现呢?那个开始菜单关机函数和任务栏的肯定不是一样的,开始菜单的比较优雅一点,提醒保存数据,通知程序退出,然后关机,而任务管理器的就相对粗暴一点,什么也不做,直接就关机,不过速度绝对一流,呵呵,我喜欢,就要这个速度。
查了下资料,一般用的是ExitWindowsEx这个函数,可能也会用InitiateSystemShutdownEx,这里交待下ExitWindowsEx的用法,查MSDN,可以看到函数原型如下:
BOOL ExitWindowsEx(
UINT uFlags, // shutdown operation
DWORD dwReason // shutdown reason
);
其中uFlags有这些选项:
EWX_LOGOFF 注销
EWX_POWEROFF 关闭系统并关闭电源
EWX_REBOOT 关机重启
EWX_SHUTDOWN 关机并指出现在可以安全关机了
还有
EWX_FORCE
EWX_FORCEIFHUNG
强制关机,可能会丢失数据。
dwReason很多,主要这么几个
SHTDN_REASON_MAJOR_APPLICATION Application issue.
SHTDN_REASON_MAJOR_HARDWARE Hardware issue.
SHTDN_REASON_MAJOR_OPERATINGSYSTEM Operating system issue.
SHTDN_REASON_MAJOR_OTHER Other issue.
SHTDN_REASON_MAJOR_POWER Power failure.
SHTDN_REASON_MAJOR_SOFTWARE Software issue.
SHTDN_REASON_MAJOR_SYSTEM System failure.
但这不是这篇文章的重点,这里要说的武器不是公开的,在MSDN中查不到,这是微软的秘密武器,ZwShutdownSystem函数,藏在ntdll.dll中。
利用ZwShutdownSystem(2)关闭电源,这个函数要求有SE_SHUTDOWN_PRIVILEGE权限,因此要先用RtlAdjustPrivilege函数来设置SE_SHUTDOWN_PRIVILEGE,SE_SHUTDOWN_PRIVILEGE的值为0x13,ZwShutdownSystem函数不通知应用程序和服务程序,就直接关闭系统了,关机速度非常快,但是如果有程序没有保存数据的话,是不会有任何提示的。
完整的程序可以这样写:
#include<windows.h>
#define SE_SHUTDOWN_PRIVILEGE 0x13
int main()
{
int nRet;
int en;
HINSTANCE hs=NULL;
typedef int (*SHUTDOWN)(int);
SHUTDOWN ZwShutdownSystem;
typedef int (*RTL_ADJUST_PRIVILEGE)(int,int,int,int *);
RTL_ADJUST_PRIVILEGE RtlAdjustPrivilege;
hs=LoadLibrary("ntdll.dll");
if(hs==NULL)
{
MessageBox(NULL,"Cannot load DLL file!","error",MB_OK);
}
ZwShutdownSystem=(SHUTDOWN)GetProcAddress(hs,"ZwShutdownSystem");
RtlAdjustPrivilege=(RTL_ADJUST_PRIVILEGE)GetProcAddress(hs,"RtlAdjustPrivilege");
nRet=RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,TRUE,TRUE,&en);
if(nRet==0x0C000007C)
nRet = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,TRUE,FALSE,&en);
nRet=ZwShutdownSystem(2);
FreeLibrary(hs);
return 0;
}
编译运行,一个黑框一闪,机子就关了,像台式机拔电源一样快速。再多想一下,给它创建一个快捷方式,换个图标,然后设置为最小化运行,就看不到黑框了,再加个快捷键,这样的话,按个键,哗一下机子就黑了,光速关机啊!
弱弱的想一下,两个方法是不是本质上是一样的呢?
二进制LED时钟--程序员的装备
今天在网上看到这样一张图片,挺有意思的,一眼看去就知道这是个时钟,但是却不一能看出时间来。程序员每天和0,1打交道,虽然没有像黑客帝国里面那样可以看懂大串的01串流,但是简短的二进制数据还是没有问题的。不过我还是没有看出中间那一串是怎么表示的时间,但是却可以通过下面的那个Calender time知道时间啊,呵呵,当然要用工具啦,不然这计算量可要命:
crane@debian:~$ date -d "@1230766664"
Wed Dec 31 18:37:44 EST 2008
呵呵,看到了吧,日期那个时钟上也写得很清楚了,不过却不知道那个小时和分钟是怎么表示的。
不过另外的一种二进制LED时钟却很容易看懂。
就像图示的那样,六列LED分成三组,分别表示时分秒,每列的四个灯从上到下的权值是8,4,2,1,把亮着的灯的权值加起来就是这列的数值了。