`
kevin-qingzhan
  • 浏览: 84837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

图形验证码

阅读更多
验证码产生类:

package com.gicom.testCode;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;

/**
* 生成随机数字或字母串,以图像方式显示,用于人工识别,使程序很难识别。减小系统被程序自动攻击的可能性。
* 生成的图形颜色由红、黑、蓝、紫4中随机组合而成,数字或字母垂直方向位置在一定范围内也是随机的,减少被程序自动识别的几率。
* 由于数字的0,1,2易和字母的o,l,z混淆,使人眼难以识别,因此不生成数字和字母的混合串。生成的串字母统一用小写,串的最大长度为16。
*
* @version
* @Since
* @See Also
* @author lchen Create Date 2005-12-16
*
*/

public class CreateValidImage {
// 字符的高度和宽度,单位为像素
private int wordHeight = 9;

private int wordWidth = 12;

// 字符大小
private int fontSize = 13;

// 最大字符串个数
private static final int MAX_CHARCOUNT = 16;

// 垂直方向起始位置
private final int initypos = 5;

// 要生成的字符个数,由工厂方法得到
private int charCount = 0;

// 随机生成字体样式
private static int[] font = { Font.BOLD, Font.ITALIC, Font.PLAIN };

// 随机生成字符串时选择的数组

private static String[] arr = { "2", "3", "4", "5", "6", "7", "8", "9",
   "A", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P",
   "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

// 随机数生成器
private Random r = new Random();

/**
  * 生成图像的格式常量,JPEG格式,生成为文件时扩展名为.jpg;输出到页面时需要设置MIME type 为image/jpeg
  */
public static String GRAPHIC_JPEG = "JPEG";

/**
  * 生成图像的格式常量,PNG格式,生成为文件时扩展名为.png;输出到页面时需要设置MIME type 为image/png
  */
public static String GRAPHIC_PNG = "PNG";

// 用工厂方法创建对象
protected CreateValidImage(int charCount) {
  this.charCount = charCount;
}

/**
  * 创建对象的工厂方法
  *
  * @param charCount
  *            要生成的字符个数,个数在1到16之间
  *
  * Return 返回RandomGraphic对象实例
  * @throws Exception
  *             参数charCount错误时抛出
  */
public static CreateValidImage createInstance(int charCount)
   throws Exception {
  if (charCount < 1 || charCount > MAX_CHARCOUNT) {
   throw new Exception(
     "Invalid parameter charCount,charCount should between in 1 and 16");
  }
  return new CreateValidImage(charCount);
}

/**
  * 随机生成一个字母和数字混合的串,并以图像方式绘制,绘制结果输出到流out中
  *
  * @param graphicFormat
  *            设置生成的图像格式,值为GRAPHIC_JPEG或GRAPHIC_PNG
  * @param out
  *            图像结果输出流
  * @return 随机生成的串的值
  * @throws IOException
  */
public String drawAlpha(String graphicFormat, OutputStream out)
   throws IOException {
  // 随机生成的串的值
  String charValue = "";
  charValue = randAlphaAndNumber();
  return draw(charValue, graphicFormat, out);

}

/**
  * 以图像方式绘制字符串,绘制结果输出到流out中
  *
  * @param charValue
  *            要绘制的字符串
  * @param graphicFormat
  *            设置生成的图像格式,值为GRAPHIC_JPEG或GRAPHIC_PNG
  * @param out
  *            图像结果输出流
  * @return 随机生成的串的值
  * @throws IOException
  */
protected String draw(String charValue, String graphicFormat,
   OutputStream out) throws IOException {

  // 计算图像的宽度和高度
  int w = (charCount + 2) * wordWidth;
  int h = wordHeight * 3;

  // 创建内存图像区
  BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
  Graphics2D g = bi.createGraphics();

  // 设置背景色
  g.setColor(getRandColor(200, 250));
  g.fillRect(0, 0, w, h);
  // 绘制边框
  g.setColor(Color.black);
  g.drawRect(0, 0, w - 1, h - 1);
  // 生成干扰线
  g.setColor(getRandColor(160, 200));
  for (int i = 0; i < 155; i++) {
   // g.setColor(getRandColor(160, 200));
   int x = r.nextInt(w);
   int y = r.nextInt(h);
   int xl = r.nextInt(12);
   int yl = r.nextInt(12);
   g.drawLine(x, y, x + xl, y + yl);
  }
  g.setColor(getRandColor(100, 159));
  for (int i = 0; i < 80; i++) {
   int x = r.nextInt(w);
   int y = r.nextInt(h);
   g.drawLine(x, y, x, y);
  }

  // 设置font
  // 绘制charValue,每个字符颜色随机
  for (int i = 0; i < charCount; i++) {
   g.setFont(new Font(null, font[randomInt(0, font.length)],
     randomInt(15, 19)));
   // g.setFont(new Font(null,Font.BOLD,randomInt(15,19)));
   String c = charValue.substring(i, i + 1);
   g.setColor(new Color(20 + r.nextInt(20), 20 + r.nextInt(20), 20 + r
     .nextInt(20)));// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
   int xpos = (i + 1) * wordWidth;
   // 垂直方向上随机
   int ypos = randomInt(initypos + wordHeight, initypos + wordHeight
     * 2);
   g.drawString(c, xpos, ypos);
  }
  g.dispose();
  bi.flush();
  // 输出到流
  ImageIO.write(bi, graphicFormat, out);

  return charValue;
}

// 生成随机数字和字符组合的字符串
private String randAlphaAndNumber() {
  String charValue = "";
  for (int i = 0; i < charCount; i++) {
   String c = arr[randomInt(0, arr.length)];
   charValue += c;
  }
  return charValue;
}

/**
  * 返回[from,to)之间的一个随机整数
  *
  * @param from
  *            起始值
  * @param to
  *            结束值
  * @return [from,to)之间的一个随机整数
  */
protected int randomInt(int from, int to) {
  // Random r = new Random();
  return from + r.nextInt(to - from);
}

private static Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色
  Random random = new Random();
  if (fc > 255)
   fc = 255;
  if (bc > 255)
   bc = 255;
  int r = fc + random.nextInt(bc - fc);
  int g = fc + random.nextInt(bc - fc);
  int b = fc + random.nextInt(bc - fc);
  return new Color(r, g, b);
}

/**
  * @param args
  * @throws Exception
  */
public static void main(String[] args) throws Exception {

  for (int i = 0; i < 10; i++) {
   System.out.println(CreateValidImage.createInstance(6).drawAlpha(
     CreateValidImage.GRAPHIC_JPEG,
     new FileOutputStream("e:/jpg/myimg" + i + ".jpg")));
  }
}
}


在Servlet中调用:

package com.gicom.testCode;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GraphicServlet extends HttpServlet {

public GraphicServlet() {
  super();

}

protected void doGet(HttpServletRequest req, HttpServletResponse res)
   throws IOException, ServletException {

  // 设置输出内容为图像,格式为jpeg
  res.setContentType("image/jpg");
  try {
   // 将内容输出到响应客户端对象的输出流中,生成的图片中包含6个字符

   String v = CreateValidImage.createInstance(6).drawAlpha(
     CreateValidImage.GRAPHIC_JPEG, res.getOutputStream());
   // 将字符串的值保留在session中,便于和用户手工输入的验证码比较,比较部分不是本文讨论重点,故略

   req.getSession().setAttribute("rv", v);
  } catch (Exception e) {

   e.printStackTrace();
  }
}
}


在JSP页面中产生图片:

<%@page contentType="text/html;charset=gb2312" language="java"%>
<%response.setHeader("Pragma", "No-cache");
   response.setHeader("Cache-Control", "no-cache");
   response.setHeader("Expires", "Thu, 01 Dec 1900 16:00:00 GMT");
   response.setDateHeader("Expires", -1);
   %>
<html>
<head>
  <title>图形代码页面</title>
</head>
<body>
  <form action="" method="post" name="form1">
   <input type="text" name="validateCode" />
   验证码:
   <img src='<%=request.getContextPath()%>/RandImage'/>
   <br>
   <input type="submit" value="提交" onclick="a()">
  </form>
</body>
</html>


原理:

产生图形码的同时,把产生的字符串存放在Session对象中,在其他的类中和用户提交过来的字符串进行比对。
分享到:
评论

相关推荐

    beego框架图形验证码实现

    【beego框架图形验证码实现】是使用Go语言开发的一个高效且功能丰富的图形验证码库,它为Web应用提供了安全的验证码生成服务。这个库的核心目的是为了防止自动化程序(如机器人)进行非法操作,如批量注册、恶意登录...

    图形验证码成功之后实现用户登录功能.zip

    在IT行业中,图形验证码是一种广泛应用于网络安全的重要技术,它的主要目的是防止自动化的恶意软件或机器人进行非法操作,如批量注册、频繁登录等。本项目"图形验证码成功之后实现用户登录功能.zip"着重于构建一个...

    JavaScript图形验证码的实现

    JavaScript验证码的简单实现,有简单的随机数字,也有较复杂的图形验证码, 这种图形验证码很高效简洁,使用爬虫是有较大难度的爬取网站信息的。 而且这种图形验证码的应用场景非常广,可用在登录注册等等需要上传...

    java生成随机加减法的图形验证码

    在IT领域,尤其是在网络安全和网页开发中,图形验证码(Captcha)是一种常用的技术,用于防止自动化的机器人程序或恶意攻击者进行非法操作。本话题主要关注如何使用Java生成包含随机加减法问题的图形验证码。这种...

    图形验证码生成合集

    在IT领域,图形验证码(CAPTCHA)是一种广泛用于防止恶意自动化程序(如机器人或爬虫)的工具。它要求用户输入图像中显示的一串字符或完成一个简单的逻辑问题,以此来验证用户是真实的人而非机器。这个压缩包文件...

    vue插件——使用canvas生成图形验证码

    在IT行业中,图形验证码是一种广泛应用于网站以防止恶意自动化脚本(如机器人)进行操作的安全机制。Vue.js作为一款流行的前端框架,它允许开发者构建高效、可复用的组件。而将canvas技术与Vue.js结合,可以创建动态...

    图形验证码识别测试工具

    【图形验证码识别测试工具】是一种专门用于自动化处理图形验证码的技术工具。在互联网安全领域,图形验证码被广泛应用于网站登录、注册、评论等场景,目的是为了防止恶意机器人或爬虫自动执行任务,保护用户账户安全...

    【JavaScript源代码】在Ant Design Pro登录功能中集成图形验证码组件的方法步骤.docx

    在默认的登录页面中,可能并未包含图形验证码的实现,因此我们需要自定义组件来实现这一功能。 1. 创建图形验证码表单控件`CaptchaInput.tsx`: 在这个文件中,我们将编写一个React组件,用于生成和验证图形验证码...

    ASP图形验证码代码

    ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码代码ASP图形验证码...

    Android生成图形验证码

    在Android平台上,生成图形验证码(CAPTCHA)是提高应用程序安全性的关键步骤,特别是在用户登录或注册过程中。图形验证码的主要目的是防止自动化的机器人程序或者恶意攻击者进行非法操作,如批量注册、恶意登录等。...

    jsp图形验证码源码

    本篇文章将详细解析基于JSP实现的图形验证码源码,帮助开发者理解和应用这种安全功能。 首先,我们需要了解JSP(JavaServer Pages)是Java的一种服务器端脚本语言,它允许开发者在HTML页面中嵌入Java代码,以动态...

    js图形验证码,只要简单的复制粘贴 3步

    ### 图形验证码实现详解:基于JS与JSP的三步法 #### 一、引言 在当前互联网安全体系中,图形验证码作为一种简单而有效的防止自动化攻击的方式,被广泛应用于登录、注册等环节,以确保操作由真实的人类用户执行而非...

    java代码中图形验证码的源代码

    ### Java代码中图形验证码的实现 #### 知识点概览 本文将深入解析一个Java图形验证码的实现案例。此案例包含了一个名为`RandCodeImage`的类,它继承自`HttpServlet`类,并实现了图形验证码的生成逻辑。通过本案例的...

    vue+uniapp实现图形验证码功能-插件(附源码)

    vue+uniapp实现图形验证码功能-插件(附源码) 在登录系统时,除了密码登录,还需要提供验证码登录。 涉及验证码,为了安全,一般会加入图形验证码,然后再发短信验证码。 一般是前端请求,通过服务后台生成图形码流...

    图形验证码(servlet实现)

    在IT领域,图形验证码(CAPTCHA)是一种广泛用于防止恶意自动化程序(如机器人或爬虫)的工具。它要求用户在提交表单之前输入显示在图像中的扭曲文本,以此来验证用户是人类而不是机器。本篇文章将深入探讨如何使用...

    asp.net生成图形验证码

    在ASP.NET中,生成图形验证码是一项常见的安全功能,用于防止自动化程序(如机器人)进行恶意操作,例如批量注册、频繁登录尝试等。图形验证码通常由一串随机字符组成,显示在一个图片上,用户需要在输入框中正确...

    四种图形验证码(含汉字ASP三种,PHP一种)

    1. ASP图形验证码: - ASP验证码通常使用服务器端脚本语言来生成随机的字符串或图像,然后将其显示在客户端。这里包含的三种ASP验证码可能包括不同的算法和技术,用于生成不同类型的图形,如扭曲文字、数字混合、...

    ios--图形验证码

    在iOS开发中,图形验证码(Captcha)是一种重要的安全机制,用于防止自动化程序或机器人进行恶意操作,如防止批量注册、频繁登录等。本项目提供了一种自定义的本地实现方式,无需依赖外部库,方便集成到你的iOS应用...

Global site tag (gtag.js) - Google Analytics