「java验证码干扰点」JAVA开发验证码

博主:adminadmin 2023-01-13 12:18:07 329

本篇文章给大家谈谈java验证码干扰点,以及JAVA开发验证码对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Java如何实现验证码验证功能

Java如何实现验证码验证功能呢?日常生活中,验证码随处可见,他可以在一定程度上保护账号安全,那么他是怎么实现的呢?

Java实现验证码验证功能其实非常简单:用到了一个Graphics类在画板上绘制字母,随机选取一定数量的字母随机生成,然后在画板上随机生成几条干扰线。

首先,写一个验证码生成帮助类,用来绘制随机字母:

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;

import javax.imageio.ImageIO;

public final class GraphicHelper {

/**

* 以字符串形式返回生成的验证码,同时输出一个图片

*

* @param width

*            图片的宽度

* @param height

*            图片的高度

* @param imgType

*            图片的类型

* @param output

*            图片的输出流(图片将输出到这个流中)

* @return 返回所生成的验证码(字符串)

*/

public static String create(final int width, final int height, final String imgType, OutputStream output) {

StringBuffer sb = new StringBuffer();

Random random = new Random();

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics graphic = image.getGraphics();

graphic.setColor(Color.getColor("F8F8F8"));

graphic.fillRect(0, 0, width, height);

Color[] colors = new Color[] { Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.BLACK, Color.ORANGE,

Color.CYAN };

// 在 "画板"上生成干扰线条 ( 50 是线条个数)

for (int i = 0; i  50; i++) {

graphic.setColor(colors[random.nextInt(colors.length)]);

final int x = random.nextInt(width);

final int y = random.nextInt(height);

final int w = random.nextInt(20);

final int h = random.nextInt(20);

final int signA = random.nextBoolean() ? 1 : -1;

final int signB = random.nextBoolean() ? 1 : -1;

graphic.drawLine(x, y, x + w * signA, y + h * signB);

}

// 在 "画板"上绘制字母

graphic.setFont(new Font("Comic Sans MS", Font.BOLD, 30));

for (int i = 0; i  6; i++) {

final int temp = random.nextInt(26) + 97;

String s = String.valueOf((char) temp);

sb.append(s);

graphic.setColor(colors[random.nextInt(colors.length)]);

graphic.drawString(s, i * (width / 6), height - (height / 3));

}

graphic.dispose();

try {

ImageIO.write(image, imgType, output);

} catch (IOException e) {

e.printStackTrace();

}

return sb.toString();

}

接着,创建一个servlet,用来固定图片大小,以及处理验证码的使用场景,以及捕获页面生成的验证码(捕获到的二维码与用户输入的验证码一致才能通过)。

import java.io.OutputStream;

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 javax.servlet.http.HttpSession;

@WebServlet(urlPatterns = "/verify/regist.do" )

public class VerifyCodeServlet extends HttpServlet {

private static final long serialVersionUID = 3398560501558431737L;

@Override

protected void service(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 获得 当前请求 对应的 会话对象

HttpSession session = request.getSession();

// 从请求中获得 URI ( 统一资源标识符 )

String uri = request.getRequestURI();

System.out.println("hello : " + uri);

final int width = 180; // 图片宽度

final int height = 40; // 图片高度

final String imgType = "jpeg"; // 指定图片格式 (不是指MIME类型)

final OutputStream output = response.getOutputStream(); // 获得可以向客户端返回图片的输出流

// (字节流)

// 创建验证码图片并返回图片上的字符串

String code = GraphicHelper.create(width, height, imgType, output);

System.out.println("验证码内容: " + code);

// 建立 uri 和 相应的 验证码 的关联 ( 存储到当前会话对象的属性中 )

session.setAttribute(uri, code);

System.out.println(session.getAttribute(uri));

}

接着写一个HTML注册页面用来检验一下:

html

head

meta charset="UTF-8"

title注册/title

link rel="stylesheet" href="styles/general.css"

link rel="stylesheet" href="styles/cell.css"

link rel="stylesheet" href="styles/form.css"

script type="text/javascript" src="js/ref.js"/script

style type="text/css" 

.logo-container {

margin-top: 50px ;

}

.logo-container img {

width: 100px ;

}

.message-container {

height: 80px ;

}

.link-container {

height: 40px ;

line-height: 40px ;

}

.link-container a {

text-decoration: none ;

}

/style

/head

body

div class="container form-container"

form action="/wendao/regist.do" method="post"

div class="form" !-- 注册表单开始 --

div class="form-row"

span class="cell-1"

i class="fa fa-user"/i

/span

span class="cell-11" style="text-align: left;"

input type="text" name="username" placeholder="请输入用户名"

/span

/div

div class="form-row"

span class="cell-1"

i class="fa fa-key"/i

/span

span class="cell-11" style="text-align: left;"

input type="password" name="password" placeholder="请输入密码"

/span

/div

div class="form-row"

span class="cell-1"

i class="fa fa-keyboard-o"/i

/span

span class="cell-11" style="text-align: left;"

input type="password" name="confirm" placeholder="请确认密码"

/span

/div

div class="form-row"

span class="cell-7"

input type="text" name="verifyCode" placeholder="请输入验证码"

/span

span class="cell-5" style="text-align: center;"

img src="/demo/verify/regist.do" onclick="myRefersh(this)"

/span

/div

div class="form-row" style="border: none;"

span class="cell-6" style="text-align: left"

input type="reset" value="重置"

/span

span class="cell-6"  style="text-align:right;"

input type="submit" value="注册"

/span

/div

/div !-- 注册表单结束 --

/form

/div

/body

/html

效果如下图:

在控制台接收到的图片中验证码的变化如下:

当点击刷新页面的时候,验证码也会随着变化,但我们看不清验证码时,只要点击验证码就会刷新,这样局部的刷新可以用JavaScript来实现。

在img

src="/demo/verify/regist.do"中,添加一个问号和一串后缀数字,当刷新时让后缀数字不断改变,那么形成的验证码也会不断变化,我们可以采用的一种办法是后缀数字用date代替,date获取本机时间,时间是随时变的,这样就保证了刷新验证码可以随时变化。

代码如下:

function myRefersh( e ) {

const source = e.src ; // 获得原来的 src 中的内容

//console.log( "source : " + source  ) ;

var index = source.indexOf( "?" ) ;  // 从 source 中寻找 ? 第一次出现的位置 (如果不存在则返回 -1 )

//console.log( "index : " + index  ) ;

if( index  -1 ) { // 如果找到了 ?  就进入内部

var s = source.substring( 0 , index ) ; // 从 source 中截取 index 之前的内容 ( index 以及 index 之后的内容都被舍弃 )

//console.log( "s : " + s  ) ;

var date = new Date(); // 创建一个 Date 对象的 一个 实例

var time = date.getTime() ; // 从 新创建的 Date 对象的实例中获得该时间对应毫秒值

e.src = s + "?time=" + time ; // 将 加了 尾巴 的 地址 重新放入到 src 上

//console.log( e.src ) ;

} else {

var date = new Date();

e.src = source + "?time=" + date.getTime();

}

}

如回答不详细可追问

JAVA验证码生成问题

贴一点我找的代码吧

例程7-11 check_code.html

h3带有验证码的登录页面/h3

form action="servlet/LogonFormServlet" method="post"

用户名:input type="text" name="name"br

密 码:input type="password" name="pass"br

验证码:input type="text" name="check_code"

img src="servlet/CheckCodeServlet"br

input type="submit" value="登录"

/form

例程7-12 CheckCodeServlet.java

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.awt.*;

import java.awt.image.*;

import javax.imageio.ImageIO;

public class CheckCodeServlet extends HttpServlet

{

private static int WIDTH = 60;

private static int HEIGHT = 20;

public void doGet(HttpServletRequest request,HttpServletResponse response)

throws ServletException,IOException

{

HttpSession session = request.getSession();

response.setContentType("image/jpeg");

ServletOutputStream sos = response.getOutputStream();

//设置浏览器不要缓存此图片

response.setHeader("Pragma","No-cache");

response.setHeader("Cache-Control","no-cache");

response.setDateHeader("Expires", 0);

//创建内存图象并获得其图形上下文

BufferedImage image =

new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

Graphics g = image.getGraphics();

//产生随机的认证码

char [] rands = generateCheckCode();

//产生图像

drawBackground(g);

drawRands(g,rands);

//结束图像的绘制过程,完成图像

g.dispose();

//将图像输出到客户端

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ImageIO.write(image, "JPEG", bos);

byte [] buf = bos.toByteArray();

response.setContentLength(buf.length);

//下面的语句也可写成:bos.writeTo(sos);

sos.write(buf);

bos.close();

sos.close();

//将当前验证码存入到Session中

session.setAttribute("check_code",new String(rands));

//直接使用下面的代码将有问题,Session对象必须在提交响应前获得

//request.getSession().setAttribute("check_code",new String(rands));

}

private char [] generateCheckCode()

{

//定义验证码的字符表

String chars = "0123456789abcdefghijklmnopqrstuvwxyz";

char [] rands = new char[4];

for(int i=0; i4; i++)

{

int rand = (int)(Math.random() * 36);

rands[i] = chars.charAt(rand);

}

return rands;

}

private void drawRands(Graphics g , char [] rands)

{

g.setColor(Color.BLACK);

g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));

//在不同的高度上输出验证码的每个字符

g.drawString("" + rands[0],1,17);

g.drawString("" + rands[1],16,15);

g.drawString("" + rands[2],31,18);

g.drawString("" + rands[3],46,16);

System.out.println(rands);

}

private void drawBackground(Graphics g)

{

//画背景

g.setColor(new Color(0xDCDCDC));

g.fillRect(0, 0, WIDTH, HEIGHT);

//随机产生120个干扰点

for(int i=0; i120; i++)

{

int x = (int)(Math.random() * WIDTH);

int y = (int)(Math.random() * HEIGHT);

int red = (int)(Math.random() * 255);

int green = (int)(Math.random() * 255);

int blue = (int)(Math.random() * 255);

g.setColor(new Color(red,green,blue));

g.drawOval(x,y,1,0);

}

}

}

例程7-13 LogonFormServlet.java

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class LogonFormServlet extends HttpServlet

{

public void service(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException

{

response.setContentType("text/html;charset=GB2312");

PrintWriter out = response.getWriter();

HttpSession session = request.getSession(false);

if(session == null)

{

out.println("验证码处理问题!");

return;

}

String savedCode = (String)session.getAttribute("check_code");

if(savedCode == null)

{

out.println("验证码处理问题!");

return;

}

String checkCode = request.getParameter("check_code");

if(!savedCode.equals(checkCode))

{

/*验证码未通过,不从Session中清除原来的验证码,

以便用户可以后退回登录页面继续使用原来的验证码进行登录*/

out.println("验证码无效!");

return;

}

/*验证码检查通过后,从Session中清除原来的验证码,

以防用户后退回登录页面继续使用原来的验证码进行登录*/

session.removeAttribute("check_code");

out.println("验证码通过,服务器正在校验用户名和密码!");

}

}

编译上面的两个Java源文件,确保编译后生成的class文件存放在了tomcat安装目录\webapps\it315\WEB-INF\classes目录中。将check_code.html文件保存在tomcat安装目录\webapps\it315目录中。

(2)在tomcat安装目录\webapps\it315\WEB-INF\web.xml文件中注册有关的Servlet,并设置其映射URL。在web.xml文件中的相应位置处增加如下两段内容:

servlet

servlet-nameCheckCodeServlet/servlet-name

servlet-classCheckCodeServlet/servlet-class

/servlet

servlet

servlet-nameLogonFormServlet/servlet-name

servlet-classLogonFormServlet/servlet-class

/servlet

……

servlet-mapping

servlet-nameCheckCodeServlet/servlet-name

url-pattern/servlet/CheckCodeServlet/url-pattern

/servlet-mapping

servlet-mapping

servlet-nameLogonFormServlet/servlet-name

url-pattern/servlet/LogonFormServlet/url-pattern

/servlet-mapping

保存web.xml文件后,重新启动Tomcat。

(3)在浏览器地址栏中输入如下地址:

浏览器中显示出如图7.25所示的效果,然后就可以对验证码的功能进行测试了

用Java做一个验证码识别的程序,要识别的验证码:http://group.bj.chinamobile.com/edsmp/ValidateNum

验证码识别,费力效果差,除非非常简单的图片,否则极难识别,而且验证码图片的代码,人家只需要稍微弄复杂点,识别的复杂度直线上升,成功率直线下降。像hotmail, google, yahoo那种就直接放弃,

不过像这种简单的,你可以试试,用模式匹配:

例如单个数字大小是16 * 16像素, 那就划分成16*16块,每个块1个像素,编号,特征就是a[0][0] - 白, a[0][1] - 白, a[0][2]黑……这种,存下来,把要识别的图片上的数字,也这样处理,然后跟保存下来的特征码进行匹配就行了,看看有多少是一样的,超过50%就可以认为找到了,或者把阈值设更低点

难点在于要识别的图片上面有干扰点,要排除,以你给出的图片来说,可以这样:

1. 先统一黑白:如果一个像素跟白色很接近,就认为是白色,否则认为是黑色。(如果底色是随机的,那就把区域色块最大的认为是白色,其他的黑色)

2. 每个像素周围有8个像素,计算出这个区域内的平均灰度,例如这9个点中超过4个是黑色,那就认为这个像素是黑色

jsp页面图形验证码与session不同步

jsp中要做到验证码同步,最好别用session,有延时问题。

以下是实现思路:

1.在jsp页面用js生成验证码并保存在变量中,验证码作为参数传到java(继承了HttpServlet)类

2.根据jsp页面中传过来的验证码画出一个有干扰线或干扰点的图片

3.在WEB-INF/web.xml中配置 servlet

4.在jsp页面调用配置好的servlet,一般是通过img src="servlet名" id="code"/调用

5.提交数据之前验证

form onsubmit="return validate();"……/

局部刷新验证码:a href="#" onclick="javascript:show();return false;"看不清,换一张!/a-

java验证码干扰点的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于JAVA开发验证码、java验证码干扰点的信息别忘了在本站进行查找喔。