首先呢,我们要明确一点,为什么要用到验证码?它解决了什么问题?该怎么用?
我们都知道,浏览器都是用html的标准与网站的服务器动态连接的,而在html的表单提交中,基本都是用post的方法来提交数据的,这样很可能被人使用机器人程序或者盗用Action的恶意程序进行批量注册和登陆尝试,从而攻击网站或者盗取他人密码。这时,验证码就有用啦,表单上会出现一个随机输出的验证码,这时采用注册机等暴力程序就会因为无法读取验证码而无能为力(也防止一些不法分子进行刷屏),保证网站的安全。
相信验证码大家都是见过的,有数字,有字母,甚至它们还有汉字,那么它们是怎么随机生成的呢?下面我们就来探讨这个问题。
?
数字的生成,在java中,java.util.Random类可以通过实例化一个Random对象来创建一个随机数生成数器。语法格式:
Random r=new Random(seedValue);
seedValue是指产生随机数的种子,一般可以用当前的时间作为种子。如:
Random r=new Random(new java.util.Date().getTime());
而生成的 r 大家都知道是一个Random对象吧?而在Random类中提供了不少方法来返回一个随机数:
public int nextInt();返回一个随机整数
public int nextInt(int n);返回一个大于0小于n的随机整数
public long nextLong();返回一个随机长整型数
public double nextDouble();返回一个随机双精度型值
public float nextFloat();返回一个随机浮点型数
。。。自己查api吧。。。
所以r.nextInt();就可以得到一个随机整数,print出来就可以了。
?
字母的生成,这个也很简单,大家都知道字母在ASCII表的值是65-90(大写字母)和97-122(小写字母),所以,只要能随机生成65-90和97-122的整数,再转换成字符型(或者字符串型,最终还是要转换成字符串的,因为验证码 最后是一个字符串嘛),那么相应的字母也就生成出来了。这个简单吧。
代码:Random r = new Random();
int upCase =?r.nextInt(26)+65;//得到65-90的随机数
int downCase = r.nextInt(26)+97;//得到97-122的随机数
String?up =String.valueOf((char)upCase);//得到A-Z
String?down =String.valueOf((char)downCase);得到a-z
?
汉字的生成,这个就比较麻烦了,所谓的麻烦是指我要解释得麻烦,要打很多字。。。
汉字是有一个全国统一的代码的,标准代号为GB2312-80,又称国标码。它规定了所有的国标汉字和符号分配在一个94行和94列的方阵里面,方阵的每一行称为一个区,01区到94区;每一列称为一个位,01位到94位。每一个汉字的区码和位码组合的4个阿拉伯数字就是它们的“区位码”(可以用他们唯一确定一个汉字)。
与汉字区位码类似的还有汉字机内码,汉字的机内码是在汉字的区位码的区码和位码上分别加上A0H(这里的H表示前两位数字为16进制数)得到的。使用机内码表示汉字占用2个字节,分别称为高位字节和地位字节,
高位字节=区码+A0H;
低位字节=位码+A0H;
如区位码为1601,区码位码分别用16进制表示为1001H,机内码的高位字节为B0H,低位字节为A1H,机内码就是B0A1H。
了解了这些之后,你就可以随机生成汉字了。代码如下(不是唯一性,参考用,懂得人可以按照自己想法随意写):
?
import java.util.Date;
import java.util.Random;
?
public class WordCode {
?
public static void main(String[] args) {
Random random=new Random();
String ctmp="";
String rbase[]={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
//生成第一位区码
int r1=random.nextInt(3)+11;//生成11-14随机数
String str_r1=rbase[r1];
//生成第二位区码
int r2;
if(r1==13){
r2=random.nextInt(10);
}
else{
r2=random.nextInt(16);
}
String str_r2=rbase[r2];
//生成第一位位码
int r3=random.nextInt(6)+10;
String str_r3=rbase[r3];
//生成第二位位码
int r4;
if(r3==10){
r4=random.nextInt(14)+2;
}else{
r4=random.nextInt(16);
}
String str_r4=rbase[r4];
//将生成的区码放入第一个元素,位码放入第二个元素
byte a[]=new byte[2];
a[0]=(byte)Integer.parseInt(str_r1+str_r2,16);//转换成16进制
a[1]=(byte)Integer.parseInt(str_r3+str_r4,16);
ctmp=new String(a);//根据字节生成汉字
System.out.print(ctmp);
}
?
}
?
有了上面之后,生成的数字啊字母啊汉字啊都以字符串的形式组合,然后创建Graphics对象放进去用图像IO输出就可以生成图片啦(打字累了,具体的下次再讲)。