Java实现中文算数验证码的实现示例(算数运算+

网友投稿 279 2022-12-01


Java实现中文算数验证码的实现示例(算数运算+

为了防止,页面向数据库暴力注册入力,用户登录暴力破解,所以加入验证码,验证码无法被软件获取上边的内容(加入算数计算,更加安全),所以在现在技术,暂时安全。

先看效果图:

第一次加载比较慢,防止无法加载验证码显示,后台获取准备好的默认正在加载图片(静态图片),后台图片获取好后,替代。

验证码效果图:

后台java图片实现类VerificationCodeTool:

package com.tsXs.fileshare.tools;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.util.HashMap;

import java.util.Map;

import java.util.Random;

import org.apache.log4j.Logger;

/**

*

* ClassName: VerificationCodeTool

* Description: creat verification code

* Date: 2015-3-3 下午08:37:55

*

*

* @author yptian@aliyun.com

*

* first made

* @version 1.0.0

*

*/

public class VerificationCodeTool {

//LOG

private static final Logger LOG =Logger.getLogger(VerificationCodeTool.class);

//verification code image width

private static final int IMG_WIDTH=146;

//verification code image height

private static final int IMG_HEIGHT=30;

//The number of interference lines

private static final int DISTURB_LINE_SIZE = 15;

//generate a random number

private Random random = new Random();

//result

private int xyresult;

//result random string

private String randomString;

//Chinese Numbers

// private static final String [] CNUMBERS = "零,一,二,三,四,五,六,七,八,九,十".split(",");

//零一二三四五六七八九十乘除加减

//Here, must be java Unicode code

private static final String CVCNUMBERS = "\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u4E58\u9664\u52A0\u51CF";

//Definition of drawings in the captcha characters font, font name, font style, font size

//static final font : In Chinese characters garbled

private final Font font = new Font("黑体", Font.BOLD, 18);

//data operator

private static final Map OPMap = new HashMap();

static{

OPMap.put("*", 11);

OPMap.put("/", 12);

OPMap.put("+", 13);

OPMap.put("-", 14);

}

/**

* The generation of image verification code

* */

public BufferedImage drawVerificationCodeImage(){

//image

BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB);

//In memory to create a brush

Graphics g = image.getGraphics();

//Set the brush color

// g.setColor(getRandomColor(200,250));

g.setColor(Color.WHITE);

//Fill the background color, using the current brush colour changing background color images

//The meaning of the four parameters respectively, starting x coordinates, starting y, width, height.

//image background

g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);

//Set the brush color

g.setColor(getRandomColor(200,250));

//image border

g.drawRect(0, 0, IMG_WIDTH-2, IMG_HEIGHT-2);

//Set disturb line color

g.setColor(getRandomColor(110, 133));

//Generate random interference lines

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

drawDisturbLine1(g);

drawDisturbLine2(g);

}

//Generate a random number, set return data

getRandomMathString();

LOG.info("验证码 : "+randomString);

LOG.info("验证码结果 : "+xyresult);

//The generated random string used to save the system

StringBuffer logsu = new StringBuffer();

for(int j=0,k = randomString.length(); j < k; j++){

int chid = 0;

if(j==1){

chid = OPMap.get(String.valueOf(randomString.charAt(j)));

}else{

chid = Integer.parseInt(String.valueOf(randomString.charAt(j)));

}

String ch = String.valueOf(CVCNUMBERS.charAt(chid));

logsu.append(ch);

drawRandomString((Graphics2D)g,ch, j);

}

//= ?

drawRandomString((Graphics2D)g,"\u7B49\u4E8E\uFF1F", 3);

logsu.append("\u7B49\u4E8E \uFF1F");

LOG.info("汉字验证码 : "+logsu);

randomString = logsu.toString();

//Release the brush object

g.dispose();

return image;

}

/**

* Get a random string

* */

private void getRandomMathString(){

//Randomly generated number 0 to 10

int xx = random.nextInt(10);

int yy = random.nextInt(10);

//save getRandomString

StringBuilder suChinese = new StringBuilder();

//random 0,1,2

int Randomoperands = (int) Math.round(Math.random()*2);

//multiplication

if(Randomoperands ==0){

this.xyresult = yy * xx;

// suChinese.append(CNUMBERS[yy]);

suChinese.append(yy);

suChinese.append("*");

suChinese.append(xx);

//division, divisor cannot be zero, Be divisible

}else if(Randomoperands ==1){

if(!(xx==0) && yy%xx ==0){

this.xyresult = yy/xx;

suChinese.append(yy);

suChinese.append("/");

suChinese.append(xx);

}else{

this.xyresult = yy + xx;

suChinese.append(yy);

suChinese.append("+");

suChinese.append(xx);

}

//subtraction

}else if(Randomoperands ==2){

this.xyresult = yy - xx;

suChinese.append(yy);

suChinese.append("-");

suChinese.append(xx);

//add

}else{

this.xyresult = yy + xx;

suChinese.append(yy);

suChinese.append("+");

suChinese.append(xx);

}

this.randomString = suChinese.toString();

}

/**

* Draw a random string

* @param g Graphics

* @param randomString random string

* @param i the random number of characters

* */

public void drawRandomString(Graphics2D g,String randomvcch,int i){

//Set the string font style

g.setFont(font);

//Set the color string

int rc = random.nextInt(255);

int gc = random.nextInt(255);

int bc = random.nextInt(255);

g.setColor(new Color(rc, gc, bc));

//random string

//Set picture in the picture of the text on the x, y coordinates, random offset value

int x = random.nextInt(3);

int y = random.nextInt(2);

g.translate(x, y);

//Set the font rotation angle

int degree = new Random().nextInt() % 15;

//Positive point of view

g.rotate(degree * Math.PI / 180, 5+i*25, 20);

//Character spacing is set to 15 px

//Using the graphics context of the current font and color rendering by the specified string for a given text.

//The most on the left side of the baseline of the characters in the coordinate system of the graphics context (x, y) location

//str- to draw string.x - x coordinate.y - y coordinate.

g.drawString(randomvcch, 5+i*25, 20);

//Reverse Angle

g.rotate(-degree * Math.PI / 180, 5+i*25, 20);

}

/**

*Draw line interference

*@param g Graphics

* */

public void drawDisturbLine1(Graphics g){

int x1 = random.nextInt(IMG_WIDTH);

int y1 = random.nextInt(IMG_HEIGHT);

int x2 = random.nextInt(13);

int y2 = random.nextInt(15);

//x1 - The first point of the x coordinate.

//y1 - The first point of the y coordinate

//x2 - The second point of the x coordinate.

//y2 - The second point of the y coordinate.

//X1 and x2 is the starting point coordinates, x2 and y2 is end coordinates.

g.drawLine(x1, y1, x1 + x2, y1 + y2);

}

/**

*Draw line interference

*@param g Graphics

* */

public void drawDisturbLine2(Graphics g){

int x1 = random.nextInt(IMG_WIDTH);

int y1 = random.nextInt(IMG_HEIGHT);

int x2 = random.nextInt(13);

int y2 = random.nextInt(15);

//x1 - The first point of the x coordinate.

//y1 - The first point of the y coordinate

//x2 - The second point of the x coordinate.

//y2 - The second point of the y coordinate.

//X1 and x2 is the starting point coordinates, x2 and y2 is end coordinates.

g.drawLine(x1, y1, x1 - x2, y1 - y2);

}

/**

* For random color

* @param fc fc

* @param bc bc

* @return color random color

* */

public Color getRandomColor(int fc,int bc){

if(fc > 255){

fc = 255;

}

if(bc > 255){

bc = 255;

}

//Generate random RGB trichromatic

int r = fc+random.nextInt(bc -fc - 16);

int g = fc+random.nextInt(bc - fc - 14);

int b = fc+random.nextInt(bc - fc - 18);

return new Color(r, g, b);

}

/**

* xyresult.

*

* @return the xyresult

*

*/

public int getXyresult() {

return xyresult;

}

/**

* randomString.

*

* @return the randomString

*

*/

public String getRandomString() {

return randomString;

}

}

生产静态验证码(为了防止,加载慢,空白显示):

package com.tsXs.fileshare.tools;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import javax.imageio.ImageIO;

import javax.swing.ImageIcon;

import javax.swing.filechooser.FileSystemView;

import org.apache.log4j.Logger;

import com.tsXs.fileshare.configuration.properties.StaticConstants;

/**

* ClassName: ImageTool

* Description: get BufferedImage creat image

* Date: 2015-3-10 下午05:05:38

*

*

* @author yptian@aliyun.com

*

* first made

* @version 1.0.0

*

*/

public class ImageTool {

//LOG

private static final Logger LOG = Logger.getLogger(ImageTool.class);

//image

private BufferedImage image;

/**

* createImage : out dest path for image

* @param fileLocation dest path

*/

private void createImage(String fileLocation) {

try {

FileOutputStream fos = new FileOutputStream(fileLocation);

BufferedOutputStream bos = new BufferedOutputStream(fos);

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

// com.sun.image.codec.jpeg.JPEGImageEncoder encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(bos);

// encoder.encode(image);

bos.flush();

bos.close();

LOG.info("@2"+fileLocation+"图片生成输出成功");

} catch (Exception e) {

LOG.info("@2"+fileLocation+"图片生成输出失败",e);

}

}

/**

* createFileIconImage :create share file list icon

* @param destOutPath create file icon save dictory

*/

public void createFileIconImage(String destOutPath){

//get properties operate tool

PropertiesTool propertiesTool = PropertiesTool.getInstance(StaticConstants.SHARE_FILE_CONFGURATION_PROPERTIES_PATH);

//get share file root path

String shareFileRootPath = propertiesTool.getPropertiesValue("FileShareRootPath");

//root dictory

File rootDictory = new File(shareFileRootPath);

//child file list

File [] fileList = rootDictory.listFiles();

//child list files

File file = null;

if(fileList != null && fileList.length>0){

LOG.info("分享文件根目录下文件数:"+fileList.length);

for(int i = 0,j = fileList.length;i < j;i++){

String fileName = fileList[i].getName();

String fileAllName = shareFileRootPath +fileName;

file = new File(fileAllName);

//get file system icon

ImageIcon fileIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file);

image = (BufferedImage) fileIcon.getImage();

if(image != null){

LOG.info("@1"+fileName+"文件的图标获取成功");

}

Graphics g = image.getGraphics();

g.drawImage(image, 0, 0, null);

String fileNameX = fileName.substring(0,fileName.lastIndexOf("."));

//out image to dest

createImage(destOutPath+"\\"+fileNameX+".png");

LOG.info("@3"+fileName+"文件的图标生成成功");

}

}

}

/**

* creatDefaultVerificationCode :create default verification code

* @param destOutPath create creatDefaultVerificationCode save dictory

*/

public void creatDefaultVerificationCode(String destOutPath){

//verification code image height

//comment to com.tss.fileshare.tools.VerificationCodeTool 65 row,please

int imgwidth=146;

int imgheight=30;

int disturblinesize = 15;

VerificationCodeTool vcTool = new VerificationCodeTool();

//default verification code

image = new BufferedImage(imgwidth, imgheight, BufferedImage.TYPE_INT_RGB);

Graphics g = image.getGraphics();

g.setColor(Color.WHITE);

g.fillRect(0, 0, 146, 30);

g.setColor(vcTool.getRandomColor(200,250));

g.drawRect(0, 0, imgwidth-2, imgheight-2);

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

vcTool.drawDisturbLine1(g);

vcTool.drawDisturbLine2(g);

}

//玩命加载中…

String defaultVCString = "\u73A9\u547D\u52A0\u8F7D\u4E2D\u2026";

String dfch = null;

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

dfch = String.valueOf(defaultVCString.charAt(i));

vcTool.drawRandomString((Graphics2D)g, dfch, i);

}

LOG.info("默然验证码生成成功");

// Graphics gvc = imagevc.getGraphics();

createImage(destOutPath+"\\defaultverificationcode.jpeg");

}

/**

* graphicsGeneration : create image

* @param imgurl display picture url . eg:F:/imagetool/7.jpg

* @param imageOutPathName image out path+naem .eg:F:\\imagetool\\drawimage.jpg

* @param variableParmeterLength ; int, third parameter length.

* @param drawString variableParmeterLength ;String [] .

*/

public void graphicsGeneration(String imgurl,String imageOutPathName,int variableParmeterLength,String...drawString) {

//The width of the picture

int imageWidth = 500;

//The height of the picture

int imageHeight = 400;

image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);

Graphics graphics = image.getGraphics();

graphics.setColor(Color.WHITE);

//drawing image

graphics.fillRect(0, 0, imageWidth, imageHeight);

graphics.setColor(Color.BLACK);

//draw string string , left margin,top margin

for(int i = 0,j = variableParmeterLength;i < j;i++){

graphics.drawString(drawString[i], 50, 10+15*i);

}

//draw image url

ImageIcon imageIcon = new ImageIcon(imgurl);

//draw image , left margin,top margin

//The coordinates of the top left corner as the center(x,y)[left top angle]

//Image observer :If img is null, this method does not perform any action

graphics.drawImage(imageIcon.getImage(), 200, 0, null);

createImage(imageOutPathName);

}

public BufferedImage getImage() {

return image;

}

public void setImage(BufferedImage image) {

this.image = image;

}

}

服务器,启动的时候,调用一次,生成默认图片到服务器“/servertempdictory/fileicon/”目录下:

//create default verification code

String fileIconDictory = serverPath+"\\servertempdictory\\fileicon";

imageTool.creatDefaultVerificationCode(fileIconDictory);

生成动态验证码,并保存值到session中(此处有登录和注册的分路,这个读者可忽略,走一条既可):

/**

* creat verification code

* */

public void verificationcode(){

//response

HttpServletResponse response = ServletActionContext.getResponse();

//request

HttpServletRequest request = ServletActionContext.getRequest();

//verification code demander

String vCdemander = request.getParameter("vcdemander");

try{

//set encoding

request.setCharacterEncoding("utf-8");

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

//Verification code tool

VerificationCodeTool vcTool = new VerificationCodeTool();

BufferedImage image = vcTool.drawVerificationCodeImage();

//Verification code result

int vcResult = vcTool.getXyresult();

String vcValue = vcTool.getRandomString();

//Set ban cache

//Cache-control : Specify the request and response following caching mechanism

//no-cache: Indicates a request or response message cannot cache

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

//Entity header field response expiration date and time are given

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

response.setDateHeader("Expires", 0);

// Set the output stream content format as image format

response.setContentType("image/jpeg");

//session

//true: if the session exists, it returns the session, or create a new session.

//false: if the session exists, it returns the session, otherwise it returns null.

HttpSession session=request.getSession(true);

//set verificationcode to session

//login

if("userlogin".equals(vCdemander)){

session.setAttribute("verificationcodeuserlogin",vcResult);

}

//regiser

if("userregister".equals(vCdemander)){

session.setAttribute("verificationcodeuserregister",vcResult);

}

//To the output stream output image

ImageIO.write(image, "JPEG", response.getOutputStream());

LOG.info("获取验证码成功 :\n验证码:"+vcValue+"\n验证码结果:"+vcResult);

} catch (Exception e) {

LOG.error("获取验证码失败",e);

}

}

用struts2实现,所以配置文件struts.xml:

/view/common/message.jsp

/view/userLogin.jsp

页面jsp显示代码:

*[验证码]:只能输入数字和负号"-"

换一张

在js中用正则,保证只能输入,最多3位,可以在数字前输入一个"-",即onkeypress保证只能输入数字和"-":

var userverificationcoderegex = /^(-{0,1}\d+){1,3}$/;

if(userverificationcoderegex.test(userverificationcode)){.....

jsp图片效果:

js动态刷新验证码:

$(document).ready(function(){

//load verificatino code

refreshvc();

});

//refresh verification code

function refreshvc(){

var path = $("#contextPath").val();

var refreshvcurl =path+"/fileshare/userverificationcode.tsXs?vcdemander=userregister&time="+new Date();

$("#verificationcodeimg").attr("src",refreshvcurl);

}

验证码验证:

/**

* checkverificationcode : check verification code equals

*/

public void checkverificationcode(){

//request

HttpServletRequest request = ServletActionContext.getRequest();

//response

HttpServletResponse response = ServletActionContext.getResponse();

//output stream

PrintWriter out = null;

//session

HttpSession session = request.getSession();

//verification code from client

String vcclient = null;

//verification code from server

String vcserver = null;

//verification code demander

String vCdemander = request.getParameter("vcdemander");

//check verification code to clien flag

String checktoclienflag = null;

try{

//get verificationcode to session

//login

if("userlogin".equals(vCdemander)){

vcclient = request.getParameter("vclogincode");

vcserver = String.valueOf(session.getAttribute("verificationcodeuserlogin"));

}

//regiser

if("userregister".equals(vCdemander)){

vcclient = request.getParameter("vcregcode");

vcserver = String.valueOf(session.getAttribute("verificationcodeuserregister"));

}

vcclient = UserController.encodingconvert(vcclient);

vcclient = vcclient == null ? "" : vcclient;

if(vcclient.equals(vcserver)){

checktoclienflag = "vcok";

}else{

checktoclienflag = "vcwrong";

}

//set no cache,content type ,encoding

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

response.setContentType("text/html");

response.setCharacterEncoding("GBK");

//output stream

out = response.getWriter();

out.print(checktoclienflag);

LOG.info("验证码:vcclient: "+vcclient+"vcserver: "+vcserver+"验证顺利");

}catch (Exception e) {

LOG.error("vcclient: "+vcclient+"vcserver: "+vcserver+"验证失败",e);

}finally{

out.flush();

out.close();

}

}

properties辅助类:

/**

* Copyright (c) 2015,TravelSky.

* All Rights Reserved.

* TravelSky CONFIDENTIAL

*

* Project Name:filesharetss

* Package Name:com.tss.fileshare.controller.tools

* File Name:PropertiesFileOperation.java

* Date:2015-2-27 下午05:30:05

*

*/

package com.tsXs.fileshare.tools;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Enumeration;

import java.util.Properties;

import org.apache.log4j.Logger;

/**

*

* ClassName: PropertiesFileOperationTool

* Description: inner class Properties file operation

* Date: 2015-2-27 下午05:10:52

*

*

* @author yptian@aliyun.com

*

* first made

* @version 1.0.0

*

*/

public class PropertiesTool {

// LOG

private static final Logger LOG = Logger.getLogger(PropertiesTool.class);

// Singleton instance

private static PropertiesTool instance = new PropertiesTool();

private static Properties properties;

/**

*

* Creates a new Singleton instance of PropertiesFileOperation.

*/

private PropertiesTool() {

}

/**

* getInstance :get properties object

* @param propertiesFilePathName properties file path and name

* @return

*/

public static PropertiesTool getInstance(String propertiesFilePathName){

properties = loadPropertiesFile(propertiesFilePathName);

return instance;

}

/**

*

* loadPropertiesFile:Load properties file by path and name

* @param propertiesFilePathName path and name of properties file

* @return properties properties

*/

private static Properties loadPropertiesFile(String propertiesFilePathName) {

Properties properties = new Properties();

InputStream isLoad = PropertiesTool.class.getClassLoader().getResourceAsStream(propertiesFilePathName);

try {

// loader properties

properties.load(isLoad);

} catch (IOException e) {

LOG.error(propertiesFilePathName + " properties file read failure", e);

} finally {

try {

isLoad.close();

} catch (IOException e) {

LOG.error("properties file stream close error",e);

}

}

return properties;

}

/**

* *

* getPropertiesValue:Get properties value by key

* @param key properties key

* @return value properties value

*/

public String getPropertiesValue(String key) {

return properties.getProperty(key);

}

public static String getInstanceByServerRealPathOfValue(String propertiesFileServerRealPathName,String key){

String pValue = null;

try {

InputStream isrLoad = new FileInputStream(propertiesFileServerRealPathName);

properties.load(isrLoad);

isrLoad.close();

pValue = properties.getProperty(key);

} catch (IOException e) {

LOG.error("Failed to get the value under the server of the properties file",e);

}

return pValue;

}

/**

*

* getProperties:Get properties by key and value

* @param key properties key

* @param value properties value

*/

public void setProperties(String filePath,String key,String value){

try {

InputStream is = new FileInputStream(filePath);

OutputStream os = new FileOutputStream(filePath);

properties.load(is);

properties.setProperty(key, value);

properties.store(os, null);

os.flush();

is.close();

os.close();

} catch (IOException e) {

LOG.error("properties file stream close error",e);

}

}

/**

*

* alterProperties:alter properties by key and value

* @param key properties key

* @param value properties value

*/

public void alterProperties(String filePath,String key,String value){

try{

InputStream is = new FileInputStream(filePath);

OutputStream os = new FileOutputStream(filePath);

properties.load(is);

properties.remove(key);

properties.setProperty(key, value);

properties.store(os, null);

os.flush();

is.close();

os.close();

} catch (IOException e) {

LOG.error("properties file stream close error",e);

}

}

/**

*

* getAllProperties:Read the properties of all the information

* @return properties information

*/

@SuppressWarnings("rawtypes")

public String getAllProperties(){

Enumeration en = properties.propertyNames();

StringBuffer sf = new StringBuffer();

while (en.hasMoreElements()) {

String key = (String) en.nextElement();

String value = properties.getProperty (key);

sf.append("\n"+key);

sf.append("=");

value = value.replace(":", "\\:");

sf.append(value);

}

return sf.toString();

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中Request请求转发详解
下一篇:java数字和中文算数验证码的实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~