代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
Java
】
验证码
作者:
网网
/ 发布于
2015/3/23
/
531
字符粘连,旋转,加大识别难度。
验证码显示使用 CaptchaUtil.create(response);
验证码校对使用 CaptchaUtil.verify(xxVo.getCaptcha());
import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; public class CaptchaUtil { protected static final Logger logger = Logger.getLogger(CaptchaUtil.class); private static final ThreadLocal<Random> threadLocalRandom = new ThreadLocal<Random>() { @Override protected Random initialValue() { return new Random(); } }; private static final String CAPTCHA_SESSION_KEY = "captcha"; private static final char[] captchaChars = new char[]{'2', '3', '4', '5', '7', '8', '2', '3', '4', '5', '7', '8', 'a', 'c', 'd', 'e', 'f', 'g', 'h', 'k', 'm', 'n', 'p', 's', 't', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; private static final String[] fonts = new String[]{"Serif", "Sanserif", "Monospace", "Dialog", "DialogInput"}; private static final int[] styles = new int[]{Font.BOLD, Font.PLAIN , Font.ITALIC, Font.ROMAN_BASELINE}; private static final Color bgColor = Color.WHITE; public static void create(HttpServletResponse response) throws IOException { Random random = threadLocalRandom.get(); String captcha = ""; for (int i = 0, length = 4; i < length; i++) { captcha += captchaChars[random.nextInt(captchaChars.length)]; } HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); session.setAttribute(CAPTCHA_SESSION_KEY, MD5.hashToHexString(captcha.toLowerCase())); BufferedImage bi = new BufferedImage(120, 55, BufferedImage.TYPE_INT_ARGB); drawCaptcha(bi, captcha); fast_shear(bi); response.setContentType("image/png"); OutputStream out; out = response.getOutputStream(); ImageIO.write(bi, "png", out); out.close(); } private static void drawCaptcha(BufferedImage bi, String captcha) { Random random = threadLocalRandom.get(); Graphics2D g = bi.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(bgColor); g.fillRect(0, 0, bi.getWidth(), bi.getHeight()); g.setColor(Color.BLACK); int length = captcha.length(); float sx = 12 + random.nextInt(21); float sy = 34 + random.nextInt(11); FontRenderContext frc = g.getFontRenderContext(); Area area = new Area(); for (int i = 0; i < length; i++) { int t = 36 + random.nextInt(3); Font font = new Font(fonts[random.nextInt(fonts.length)], styles[random.nextInt(styles.length)], t); GlyphVector glyphVector = font.createGlyphVector(frc, captcha.substring(i, i + 1)); Shape glyph = glyphVector.getGlyphOutline(0, sx, sy); area.add(new Area(glyph)); double w = glyph.getBounds2D().getMaxX() - glyph.getBounds2D().getMinX(); sx += w - (w / 5.2); } g.fill(area); g.dispose(); } private static void fast_shear(BufferedImage bi) { Random random = threadLocalRandom.get(); Graphics2D g = bi.createGraphics(); int w = bi.getWidth(); int h = bi.getHeight(); int ox = 10 + random.nextInt(11); int oy = 10 + random.nextInt(11); double sx = Math.PI * 2 * random.nextDouble() * 100; double sy = Math.PI * 2 * random.nextDouble() * 100; double rx = 0.5 + random.nextDouble() * 1.0; double rt = 1.5 - rx; double ry = rt / 3 + random.nextDouble() * rt / 3 * 2; double cx = w / rx / Math.PI / 2; double cy = h / ry / Math.PI / 2; for (int i = 0; i < h; i++) { double d = (double) (ox >> 1) * Math.sin((double) i / (double) cx + sx); g.copyArea(0, i, w, 1, (int) d, 0); g.setColor(bgColor); g.drawLine((int) d, i, 0, i); g.drawLine((int) d + w, i, w, i); } for (int i = 0; i <= w; i++) { double d = (double) (oy >> 1) * Math.sin((double) i / (double) cy + sy); g.copyArea(i, 0, 1, h, 0, (int) d); g.setColor(bgColor); g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d + h, i, h); } g.dispose(); } public static boolean verify(String captcha) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); String value = (String) session.getAttribute(CAPTCHA_SESSION_KEY); if (value != null) { if (value.equals(MD5.hashToHexString(captcha.toLowerCase()))) { return true; } } return false; } }
试试其它关键字
验证码
同语言下
.
List 切割成几份 工具类
.
一行一行读取txt的内容
.
Java PDF转换成图片并输出给前台展示
.
java 多线程框架
.
double类型如果小数点后为零则显示整数否则保留两位小
.
将图片转换为Base64字符串公共类抽取
.
sqlParser 处理SQL(增删改查) 替换schema 用于多租户
.
JAVA 月份中的第几周处理 1-7属于第一周 依次类推 29-
.
java计算两个经纬度之间的距离
.
输入时间参数计算年龄
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
网网
贡献的其它代码
(
3
)
.
文件树
.
验证码
.
仿京东商品多图展示
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3