|
有时候在我们的网络应用中,防止程序自动登录搞破坏,我们一般都会加上验证码,这些验证码一般来说都是由人来识别的,当然,如果验证码很有规律,或者说很清楚,漂亮,那么也是可能被程序识别的,我以前就识别过某网站的验证码,因为比较有规律,所以被识别了,并且识别率达到99%左右,其实我们可以制作很复杂一点的验证码,添加一些干扰的线条或者字体变形,使程序识别的难度加大,这样,我们的目的也就达到了.下面是生成的图片:500)this.width=500'>代码如下,JSP代码
<%@page contentType="image/jpeg"%><%@page pageEncoding="UTF-8"%><%@ page import="java.awt.*,javax.imageio.*,java.io.*,java.util.*,java.awt.image.*" %><%--The taglib directive below imports the JSTL library. If you uncomment it,you must also add the JSTL library to the project. The Add Library500)this.width=500'> actionon Libraries node in Projects view can be used to add the JSTL 1.1 library.--%><%--<%@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"><%!String s="";%><%java.util.List<String> fonts=new ArrayList<String>();GraphicsEnvironment.getLocalGraphicsEnvironment().preferLocaleFonts();String[] names=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.CHINA);for(String s:names){ char c=s.charAt(0); if(Character.isLowerCase(c)||Character.isUpperCase(c)){ }else{ fonts.add(s); }}BufferedImage bi=new BufferedImage(200,50,BufferedImage.TYPE_INT_RGB);Graphics2D g=bi.createGraphics();char[] cs={'0','1','2','3','4','5','6','7','8','9'};char[] use=new char[4];g.setColor(new Color(240,240,240));g.fillRect(0,0,200,50);for(int i=0;i<4;i++){ Point p=new Point(5+(i*((int)(Math.random()*10)+40)),40); int size=0; int[] sizes=new int[20]; for(int j=0;j<20;j++){ sizes[j]=30+j; } size=sizes[(int)(Math.random()*sizes.length)]; int face=0; if(Math.random()*10>5){ face=Font.BOLD; }else{ face=Font.ITALIC; } use[i]=cs[(int)(Math.random()*cs.length)]; g.setPaint(new GradientPaint(p.x,p.y,new Color((int)(Math.random()*256),0,(int)(Math.random()*256)), p.x,p.y-size,new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256)))); g.setFont(new Font(fonts.get((int)(Math.random()*fonts.size())),face,size)); g.drawString(""+use[i],p.x,p.y);}s=new String(use);session.setAttribute("code", s);g.setPaint(null);for(int i=0;i<4;i++){ g.setColor(new Color((int)(Math.random()*0x00FFFFFFF))); g.drawLine((int)(Math.random()*200),(int)(Math.random()*50),(int)(Math.random()*200),(int)(Math.random()*50));}Random random = new Random();for (int i=0;i<88;i++) { int x = random.nextInt(200); int y = random.nextInt(50); g.setColor(new Color((int)(Math.random()*0x00FFFFFFF))); g.setStroke(new BasicStroke((float)(Math.random()*3))); g.drawLine(x,y,x,y);}OutputStream ot=response.getOutputStream();ImageIO.write(bi,"JPEG",ot);g.dispose();ot.close();%>以下是Servlet代码
/* * Code.java * * Created on 2007年9月21日, 下午12:08 */package com.hadeslee;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Font;import java.awt.GradientPaint;import java.awt.Graphics2D;import java.awt.GraphicsEnvironment;import java.awt.Paint;import java.awt.Point;import java.awt.Stroke;import java.awt.image.BufferedImage;import java.io.*;import java.util.ArrayList;import java.util.List;import java.util.Locale;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.*;import javax.servlet.http.*;/** * * @author lbf * @version */public class Code extends HttpServlet { /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response */ private List<String> fonts=new ArrayList<String>(); public Code(){ initFonts(); } private void initFonts(){ GraphicsEnvironment.getLocalGraphicsEnvironment().preferLocaleFonts(); String[] names=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.CHINA); for(String s:names){ char c=s.charAt(0); if(Character.isLowerCase(c)||Character.isUpperCase(c)){ }else{ fonts.add(s); } } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/jpeg;charset=UTF-8"); OutputStream out=response.getOutputStream(); BufferedImage bi=new BufferedImage(200,50,BufferedImage.TYPE_INT_RGB); Graphics2D g=bi.createGraphics(); char[] cs={'0','1','2','3','4','5','6','7','8','9'}; char[] use=new char[4]; g.setColor(new Color(240,240,240)); g.fillRect(0,0,200,50); for(int i=0;i<4;i++){ Point p=getPoint(i); int size=getSize(); use[i]=cs[(int)(Math.random()*cs.length)]; // g.setColor(new Color((int)(Math.random()*256),0,(int)(Math.random()*256))); g.setPaint(getPaint(p,size)); g.setFont(new Font(fonts.get((int)(Math.random()*fonts.size())),getFace(),size)); g.drawString(""+use[i],p.x,p.y); } g.setStroke(new BasicStroke(1.0f)); g.setPaint(null); for(int i=0;i<4;i++){ g.setColor(new Color((int)(Math.random()*0x00FFFFFFF))); g.drawLine((int)(Math.random()*200),(int)(Math.random()*50),(int)(Math.random()*200),(int)(Math.random()*50)); } Random random = new Random(); for (int i=0;i<88;i++) { int x = random.nextInt(200); int y = random.nextInt(50); g.setColor(new Color((int)(Math.random()*0x00FFFFFFF))); g.setStroke(getStroke()); g.drawLine(x,y,x,y); } ImageIO.write(bi,"JPEG",out); out.close(); g.dispose(); } private Stroke getStroke(){ BasicStroke bs=new BasicStroke((float)(Math.random()*3)); return bs; } private Point getPoint(int index){ return new Point(5+(index*((int)(Math.random()*10)+40)),40); } private Paint getPaint(Point p,int size){ GradientPaint gp=new GradientPaint(p.x,p.y,new Color((int)(Math.random()*256),0,(int)(Math.random()*256)), p.x,p.y-size,new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256))); return gp; } private int getFace(){ if(Math.random()*10>5){ return Font.BOLD; }else{ return Font.ITALIC; } } private int getSize(){ int[] sizes=new int[20]; for(int i=0;i<20;i++){ sizes[i]=30+i; } return sizes[(int)(Math.random()*sizes.length)]; } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Short description"; } // </editor-fold>}在这里我们先得到了服务器所在的系统的字体,并用这些字体生成不同的字符,然后再随机设大小,随机变形,然后为字体加上渐变,并给整个图片添加干扰线条以及干扰点.让程序识别的难度加大.呵呵,我们可以把它改成字母或者中文的验证,道理都是一样的,只不过在生成的时候,不一定用数字了,而是用所有可以输入的文字.这样,被程序识别的可能又小了. |