验证码之图片验证码

Posted sunny-su

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了验证码之图片验证码相关的知识,希望对你有一定的参考价值。

自学了短信验证码之后,总觉得安全性不是特别好,和图片的验证码结合之后感觉安全性能会更加好一点,所以选择又学了图片的。

图片的验证码在于我们对图片的获取,去掉外周的颜色等进行比较。以下我以一个简单的来说明。

这里我利用的是自己画图实现的,即用画图的方式来实现的,这样不在需要什么像第三方的什么凭证才可以使用,这种简单易学,也能达到一定的效果,故目前先只是研究了这种简单的。

当点击看不清楚,也可以实现验证码的改变。只要也就是两个代码的实现,类似于短信的验证,只不过短信的验证需要我们有第三方的接口才可以实现将随机的数字发送到相应的手机上。

前段的代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"

         pageEncoding="UTF-8"%>

         <%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<script type="text/javascript">

  function reloadCode(){

           //定义的变量为了实现浏览器的刷新(因为本身存在缓存)这是由于IE浏览器造成的原因

           var time=new Date().getTime();

           //这里是根据图片的id获取内容的

           document.getElementById("imagecode").src="<%=request.getContextPath()%>/ImageServlet?operation=checkCode&d="+time;

         }

</script>

<body>

         <form action="ImageServlet?operation=submitCode" method="post">

                   <input type="text" id="images" name="checkcode">

                    <img alt="验证码" id="imagecode" src="<%=request.getContextPath()%>/ImageServlet?operation=checkCode">

                   <a href="javascript:reloadCode()">看不清楚</a><br />

                   <input type="submit" value="提交">

         </form>

</body>

 

</html>

后台的代码:

package com.igeekhome.image;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Random;

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;

 

@WebServlet("/ImageServlet")

public class ImageServlet extends HttpServlet {

         private static final long serialVersionUID = 1L;

    public ImageServlet() {

        super();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

             String op = request.getParameter("operation");

             System.out.println("当前的操作为------------"+op);

             if("checkCode".equals(op)) {

                       checkCode(request, response);

             }

             if("submitCode".equals(op)) {

                       submitCode(request, response);

             }

    }

        

         protected void checkCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   request.setCharacterEncoding("utf-8");

                   response.setHeader("Context-type", "text/html;Charset=utf-8");

                   //绘制图片,基于JFrame实现的以及Spring中的绘图

                   //BufferedImage.TYPE_INT_RGB 图片的类型

                   BufferedImage bi = new BufferedImage(60, 80, BufferedImage.TYPE_INT_RGB);

                   //创建一个面板图片的雏形

                   Graphics g = bi.getGraphics();

                   Color c = new Color(200,150,255);//color(rgb)取色

                   g.setColor(c);

                   g.fillRect(0, 0, 60, 80);

                   //自己创建验证码的范围

                   char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();

                   //创建随机数

                   Random r = new Random();

                   //记录位置随机并设置随机数的长度

                   int index;

                   int len = ch.length;

                   //获取随机的四个数据 保存随机生成的图片

                   StringBuffer sb = new StringBuffer();

                   for(int i = 0;i<4;i++) {

                            //随机获取到的数据(字符/数字)

                            index = r.nextInt(len);

                            //随机产生一个颜色给图片即我们需要生成的四个图片

                            g.setColor(new Color(r.nextInt(88),r.nextInt(155),r.nextInt(255)));

                            //将字符画到相应的位置去,此时和我们的位置有关,我们需要画四个图片ch[index]+""字符与字符串的转换

                            g.drawString(ch[index]+"",(i*15)+3,30);

                            //保存图片

                            sb.append(ch[index]);     

                   }       

                   System.out.println("随即生成的四个随即的数据字符+数字:"+sb);

                   //将写在图片上的数字保存在session 中以便于后边的校验

                   request.getSession().setAttribute("piccode", sb.toString());

                   //输出第一个参数是指输出的对象           第二个参数是指 输出格式类型                  第三个参数是指输出到那

                   ImageIO.write(bi, "JPG", response.getOutputStream());

                   //此处不能够在转发,因为已经使用过了write输出了内容,故不能在使用转发

                   //因为输出时已经证明有了response去响应过了,没有必要再去取响应

                   //否则会报如下错Cannot forward after response has been committed

                   //request.getRequestDispatcher("Image.jsp").forward(request, response);

         }

         public String submitCode(HttpServletRequest request, HttpServletResponse response) throws IOException {

                   response.setContentType("text/html;charset=utf-8");

                   //获取发送到页面的验证码

                   String piccode = (String) request.getSession().getAttribute("piccode");

                   //获取到用户输入的验证码

                   String checkcode = request.getParameter("checkcode");

                   //将输入验证码转为大写

                   checkcode = checkcode.toUpperCase();

                   //输出流用于获得输出

                   PrintWriter out = response.getWriter();

                   //比较两个是否是匹配的

                   if(checkcode.equals(piccode)) {

                            out.println("验证码正确");

                   }else {

                            out.println("验证码错误");

                   }

                   out.flush();

                   out.close();

                   return null;

         }

         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   this.doGet(request, response);

         }

}

通过上边的两个代码便可以实现了。

以上是关于验证码之图片验证码的主要内容,如果未能解决你的问题,请参考以下文章

中文点选验证码之自动识别

验证码之图像验证码

网络安全丨中文点选验证码之自动识别

WebUI智能识别验证码之tesseract

短信验证码之验证码回显

01_验证码之字符验证码