一、简介
1.什么是图形验证码
图形验证码(Graphic Verification Code)是一种常用于网络注册、登录等场景下的验证码方式。它通常由一张随机生成的图片组成,图片中包含数字、字母或其他随机组合,用户需要正确识别并输入其中的字符或数字才能完成验证。图形验证码是为了防止机器人程序自动化攻击,保障网络安全的一种防范措施。它具有一定的复杂度和难度,通常比普通的文字验证码更难被自动化程序破解。
2.验证码的分类
验证码按照不同的特征可以分为多种类型,以下是一些常见的验证码分类:
1. 图形验证码:使用随机生成的图形来让用户进行识别验证,如数字、字母、图形等。
2. 短信验证码:通过发送短信给用户来获取验证码,用户需要输入短信中的验证码才能完成验证。
3. 语音验证码:通过语音电话给用户来获取验证码,用户需要听取语音中的验证码并输入才能完成验证。
4. 滑动验证码:用户需要按照指定轨迹滑动拼图或滑动滑块等,以完成验证。
5. 人机识别验证码:如在验证时要求用户进行计算、图片选择、控件操作等,以判断用户是否为真人进行验证。
6. 二维码:通过识别二维码进行验证,如扫描二维码登录等。
7. 生物特征识别验证码:如指纹、面部识别等。
以上是一些常见的验证码分类,不同类型的验证码在使用时都有其特定的场景和作用。
二、 验证码效果
1.效果一
1.1实现代码
package com.school.web.controller;
/**
* 验证码
*/
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
@WebServlet("/CheckCodeController")
public class CheckCodeController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//禁用缓存(目的是防止前后台验证码不一致)
resp.setHeader("pragma","No-cache");
resp.setHeader("Cache-Control","No-cache");
resp.setDateHeader("Expires",0);
//设置文件类型
resp.setContentType("image/gif");
int width = 100;
int height = 40;
//画板
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//画笔
Graphics g = image.createGraphics();
//设置字体
Font font = new Font("仿宋",Font.BOLD,25);
g.setFont(font);
//获取背景图片
String imagepath = req.getServletContext().getRealPath("/img/222.png");
Image image1 = ImageIO.read(new File(imagepath));
//设置画板的宽高
g.drawImage(image1, 0, 0, 100, 40, null);
//验证码的范围
String source = "0123456789abcdefghijklmnopqrstuvwxyz";
//保存验证码
String infor = "";
for (int i = 0; i <4 ; i++) {
int index = new Random().nextInt(source.length()-1);
char mycode = source.charAt(index);
Random random = new Random();
//设置字体颜色
g.setColor(new Color(20+random.nextInt(120),20+random.nextInt(120),20+random.nextInt(120)));
//设置字体位置
g.drawString(mycode+"",15+i*20,20+new Random().nextInt(10));
//设置干扰线
g.drawLine(random.nextInt(100),random.nextInt(20),random.nextInt(100),random.nextInt(20));
//拼接验证码
infor += mycode;
}
//传到Session域中
req.getSession().setAttribute("infor",infor);
g.dispose();
OutputStream out = resp.getOutputStream();
ImageIO.write(image,"gif", out);
out.flush();
out.close();
}
}
<a style="cursor: hand" onclick="clickrefresh()"><img alt="加载中..." id="validateimg" src="${pageContext.request.contextPath}/CheckCodeController"></a>
<script>
function clickrefresh() {
document.getElementById("validateimg").src=document.getElementById("validateimg").src+"?"+new Date().getTime();
}
</script>
注意:js中需要拼接当前时间的毫秒数,不然验证码不会刷新。
1.2运行效果
2.效果二
2.1实现代码
新建一个文件存放字符串验证码
读取外部文件的类
package com.school.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ReadFileDemo {
public static Properties readFilef(String str){
InputStream in = ReadFileDemo.class.getClassLoader().getResourceAsStream(str);
Properties p = new Properties();
try {
p.load(in);
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
获取到文件中的随机一条数据
package com.school.utils;
import java.util.Properties;
import java.util.Random;
public class CodeUtil {
public static String getAdvertising(){
Properties properties = ReadFileDemo.readFilef("file/aa.properties");
String[] str = new String[5];
for (int i = 0; i < 5 ; i++) {
str[i] = properties.getProperty("adv"+i);
}
int temp = new Random().nextInt(5);
return str[temp];
}
}
实现2个随机字符变色
package com.school.web.controller;
/**
* 验证码
*/
import com.school.utils.CodeUtil;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
@WebServlet("/CheckCodeController1")
public class CheckCodeController1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//禁用缓存
resp.setHeader("pragma","No-cache");
resp.setHeader("Cache-Control","No-cache");
resp.setDateHeader("Expires",0);
//设置文件类型
resp.setContentType("image/gif");
int width = 160;
int height = 40;
//画板
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//画笔
Graphics g = image.createGraphics();
//设置字体
Font font = new Font("仿宋",Font.BOLD,16);
g.setFont(font);
//获取背景图片
String imagepath = req.getServletContext().getRealPath("/img/222.png");
Image image1 = ImageIO.read(new File(imagepath));
//设置画板的宽高
g.drawImage(image1, 0, 0, 160, 40, null);
//验证码的范围
Random random = new Random();
//保存2个红色字
String infor = "";
//使用封装的方法获取字符串验证码
String mycode = "";
mycode = CodeUtil.getAdvertising();
//获取两个随机的字符位置
int n1 = random.nextInt(mycode.length());
int n2 = random.nextInt(mycode.length());
//防止出现相同
while (n1==n2){
n2 = random.nextInt(mycode.length());
}
//获取字符
char c1 = mycode.charAt(n1);
char c2 = mycode.charAt(n2);
//拼接
infor += c1+""+c2;
for (int j = 0; j < mycode.length(); j++) {
char outp = mycode.charAt(j);
//找到字符在字符串中的位置并将字设置成红色
if (c1==outp || c2==outp) {
g.setColor(Color.red);
}else {
g.setColor(Color.white);
}
//设置字体位置
g.drawString(outp + "", 10 + j * 20, 25 + new Random().nextInt(5));
}
req.getSession().setAttribute("infor",infor);
g.dispose();
OutputStream out = resp.getOutputStream();
ImageIO.write(image,"gif", out);
out.flush();
out.close();
}
}